-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
To debug Implicit ATR Flowsheet #4
Conversation
The error I get when running this flowsheet is |
I did not get any helpful error description. I got this: Cannot execute code, session has been disposed. Please try restarting the Kernel. |
Yep, that's almost definitly a segfault caused by this error happening in ASL. We can solve this flowsheet with Ipopt via the nl interface, so we know we both have the There might be some difference caused by us using IDAES's Ipopt? I hope not. |
I will try to keep searching for possible modeling errors in this flowsheet. |
I've narrowed this down and it seems to be a bug in ASL when reading two nl files and the second uses different external function libraries than the first. See ampl/asl#13. Hopefully the ASL maintainers can fix this quickly, otherwise we'll have to implement some workaround in Pyomo (not that difficult, but a little ugly). |
The workaround isn't horrible, just the following at the top of the file: import os
os.environ["AMPLFUNC"] = "\n".join(
[
"/path/to/.idaes/bin/cubic_roots.so",
"/path/to/.idaes/bin/functions.so",
]
) Ideally, we get these library paths directly from IDAES. The question is how to identify all the external functions we need before instantiating the implicit function. This can lead to multiple libraries defining the same external function (because ASL will see e.g. the |
########## REFORMER OUTLET PRESSURE ########## | ||
m.fs.reformer.outlet.pressure.fix(137895) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is reformer outlet pressure fixed in this flowsheet? The inlet pressure is not fixed, is it? Should a pressure drop be fixed instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The inlet pressure to the reformer is fixed at 203396 Pa.
Air inlet pressure to reformer_mix: 203396 Pa
Steam inlet pressure to reformer_mix: 203396 Pa
Gas inlet pressure to reformer_mix (outlet of NG Expander): 203396 Pa.
Outlet reformer pressure is fixed to 137895 Pa as in the original flowsheet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the reminder. It might be better to go with a fixed pressure drop instead, as that will be correct even if we eventually change the inlet pressure (and will cause less confusion).
After I added the workaround for the external function libraries, I got a KeyError because of external variables being included in the constraints of the "explicit model". I remedied this by just using the Gibbs reactor outlet arc equations as the residual equations. Now we don't have to add dummy variables and replace the "original variables" with them in the rest of the model. However, the model has trouble converging. I have tried with a couple different initializations and variations of the inner Newton solver, but I either get an evaluation error, or a residual that Ipopt is unable to converge. This could be a bug in how we are constructing the implicit function (or how I am evaluating the function and its derivatives under the hood), or it could be something difficult about the implicit function system. I will continue to debug. |
Sounds good. This is what I plan to do next week:
|
I found a bug in the setup of the implicit function. I had the recuperator inlet arc's pressure equality included in the residual equations, even though pressure was not set as an input. This script now works for me and solves to the same value as the full-space flowsheet. @sbugosen can you try the script and let me know if it works for you? The solve only seems to converge with good initialization (i.e. after solving a square problem via the decomposition). Otherwise I get an evaluation error. I'll work on handling evaluation errors in PyNumero and CyIpopt, but until then, if we want to use this, we'll have to use the "good initialization". If we do so, we should use this initialization for the other formulations (full-space and surrogate) to be fair. |
That iteration count sounds right to me. Yep, it does take longer, especially once the imprecision in the implicit function solve starts to effect Ipopt's ability to reduce infeasibility, around 1e-5 or so. And yes, we expect the flowsheet with the implicit reactor to have the number of variables of the original flowsheet minus the number of external variables. I believe there are 897 variables in the original flowsheet and 55 external variables, so 842 looks like the right number of variables to me. |
Got it, yes, I forgot that was the number of external vars. So main modifications to make the flowsheet work:
I want to document this so that I'm clear on what to expect when we do a more complex flowsheet. |
My to-dos on this PR:
@sbugosen Can you (a) confirm that the surrogate models replace the mixer as well as the reformer and (b) point me to the initialization routine you have been using? |
@Robbybp Yes (b) point me to the initialization routine you have been using? When I used this good initialization routine for Full Space and Implicit:
The Full Space and the Implicit converged all instances. The make_simulation found an optimal solution in every instance, and this helped a lot for the optimization to be successful. To get around this small issue, I read your Implicit Function paper again and found this: "Compared with simultaneous dynamic optimization, using implicit functions to solve optimization problems in a reduced space has several advantages. While simultaneous dynamic optimization formulations and nonlinear optimization solvers are relatively mature, their convergence is sensitive to an initial guess and to scaling of variables and constraints. We note that a reduced space formulation leaves a user with fewer variables to initialize and scale." So to prove that initialization shouldn't matter much for the implicit function, I used this routine instead:
In many cases, this routine did not find an optimal solution, but the implicit optimization did, regardless of this. This is good. My results are that full space converged only 38 out of 64 optimization instances, while implicit converged 53 out of 64. |
This paper supports the fact that initializing the optimization problem with a feasible solution really helps convergence. https://www.sciencedirect.com/science/article/pii/S0140700713002909#bib5 |
This is the first iteration of the ATR Implicit Flowsheet. Everything runs up until the solver, where my kernel automatically dies.
Potential issues: