-
Notifications
You must be signed in to change notification settings - Fork 241
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
Pressure changer initialization guesses #1556
base: main
Are you sure you want to change the base?
Pressure changer initialization guesses #1556
Conversation
I realise after writing up this PR it may be easier (and more maintainable?) to revert back to using the normal control volume initialization. I think the control volume initialization would just need to be modified to take into account Some logic would still need to be kept for the |
@alma-walmsley My first observation here is that you are using the old initialization API which is on the path to deprecation and that it would be better to switch to the new Also, it might help to clarify what you mean by "This occurs for me since I am setting constraints to "define" the state variables. "; are these constraints being added to you pressure changer directly? If so, then this violates some of the assumption that went into the design of the initialization routine, i.e., that the inlet conditions would be fixed by something upstream and would have the correct/desired values and thus can be used directly (that said, the first step really should be to initialize the inlet state before projecting the outlet to handle different sets on state variables). |
This is the same as mentioned in #1554, but I will add it here for clarity: Suppose we know the value of the m.fs.compressor = Compressor(property_package=m.fs.properties)
m.fs.compressor.isentropic_efficiency[0].fix(1)
m.fs.compressor.control_volume.properties_in[0].temperature.fix(280) # K
m.fs.compressor.control_volume.properties_in[0].pressure.fix(100000) # Pa
m.fs.compressor.control_volume.properties_out[0].pressure.fix(200000) # Pa
# add a constraint for flow_mass to the state block
m.fs.compressor.control_volume.properties_in[0].add_component(
"flow_mass_constraint", Constraint(rule=m.fs.compressor.control_volume.properties_in[0].flow_mass == 10) # kg/s
) The IDAES initialization routine usually expects the state var However, the guesses provided to the outlet state block are determined before the inlet state is solved. So the correct
Exactly this, which is what is done in this PR (but not handling different state variables). Which the control volume initialization handles properly. I will also have a look at the new |
Given my comment on the other PR, I would suggest trying out the new |
@alma-walmsley, you should be able to fix the black failure by just running |
Considering the more "discussion-y" nature of this PR, I'm converting it to Draft for the time being. |
Actually I think it is ready for review; I will try to explain in depth what is going on here: We are currently using The root of the problem is the order that things are done:
This PR changes the order so that:
Why is this a problem?If the inlet state variables change during inlet state initialization, then the guesses that were passed to the outlet are incorrect (since these guesses were passed beforehand). In our case, the value of an inlet state variable would change if the user does not know the value of it, but does know the value of one of the expressions on the state block. The state variable is unfixed, and a constraint is added for an expression. For example, if However, this breaks the rules of initialization - that all state variables should be fixed. Instead, a guess for However, this will cause problems with a bad
The reasoning behind doing it this way is because it is easier to solve a smaller model (ie. a single state block) rather than something more complex (ie. a unit model). Whether you agree with the above approach or not (which describes how the issue appears in our case), doesn't really affect the validity of this PR. It will not affect anything if the inlet state variables remain constant during initialization. And why shouldn't I be able to use a custom state block that changes the values of the state variables, but maintains them being fixed (for the unit model level)? This problem is unique to the |
The problem is that everything about IDAES has been designed so that, if inlet state variables are fixed and a certain set of process variables are fixed, then the unit model is square and can be solved independently. This features not just in initialization, but also the way information is passed between unit models using arc constraints. Ideally, the user should only be specifying information about the state variables in I'm not sure exactly how you're deviating from this workflow (except possibly by not including I'm willing to consider merging this PR if it's helpful in the short term, because it doesn't appear to cause any issues for people using the conventional IDAES workflow. However, I would strongly recommend bringing your process in line with what I outlined, because I'm not willing to spend time and effort supporting a workflow designed to avoid specifying state variables. |
For clarification, I'm suggesting a workflow like:
Let me know if you have comments or questions about this. I'd be interested in hearing @andrewlee94 's take on things, if he's around and has any spare time. |
Fixes # .
Summary/Motivation:
The pressure changer initialization routine does not use the normal control volume initialization routine. I assume this is because it needs to take into account
ratioP
for its outlet pressure guess? See d15028f.The pressure changer initialization differs in that it sets up guesses for the outlet state before the inlet state is initialized. This means if the values of the inlet state vars were to change during the inlet initialization, the guesses for the outlet state are now incorrect. (The control volume initialization does not have this problem since it estimates the outlet state after inlet state initialization).
This occurs for me since I am setting constraints to "define" the state variables. The inlet guess may well be the default value, and change during initialization to conform to a constraint. Which is fine, except that the same (stale) inlet guess is used when initializing the outlet state block, and it may be fixed there... leading to problems in later stages of initialization.
Instead, the outlet guesses should be created from the inlet state after the inlet state is initialized.
Changes proposed in this PR:
state_args_out
to after theproperties_in
initializationinit_isentropic
andinit_adiabatic
Legal Acknowledgement
By contributing to this software project, I agree to the following terms and conditions for my contribution: