-
-
Notifications
You must be signed in to change notification settings - Fork 355
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
WIP: 1d point control #1510
WIP: 1d point control #1510
Conversation
Is there a reference for just the general coordinate/layout of the stagnation flow problem in the StFlow class? I know it's based on the stagnation flow sections in Kee's book. I was just wondering if there was anything regarding the coordinate system, where the origin is located, etc. |
I'm not quite sure what you mean. I assume you've seen https://cantera.org/science/flames.html? The location of the origin (z=0) is arbitrary, though as a practical matter the first grid point is set as z=0 and positive z values for subsequent grid points in all of the pre-configured flame types in Cantera. |
Thanks Ray. I reviewing the 1D numerical coding in the StFlow.cpp file with regards to what the 'left' and 'right' boundaries were in the context of the axisymmetric stagnation flow configuration. Things like the unwinding scheme that Kee describes in his book, and how the Lambda equation(c_offset_L) is treated. To make sure I understand, the fuel bc is z=width and the oxidizer bc is z=0 for the counterflow flame configuration? |
There was an issue in the Sim1D.cpp implementation of the method for finding the coordinate of the control point based on temperature, as well as the coding in StFlow.cpp implementation for the residuals at the control points. The coding swapped from @axbriones approach of identifying the grid index of the point in the domain that was to be used for controlling the flame, and so the loop over the grid indices checked for integer equality. The newer work changed to a coordinate-based identification of the flame control point location, using floating point numbers, but the other parts of the code that used to check for grid index equality between integers just had the integers swapped out for the floating point numbers. Floating point comparisons are definitely not the way to go. I added an epsilon for comparing the equality of two floating point numbers. I'm not sure why the original grid index based way of locating the control point was moved away from. Possibly related to grid refinement changing the number of grid points? |
00963a6
to
d48d11a
Compare
d48d11a
to
f73292e
Compare
… residual function into small equation-specific function calls for each equation.
…or floating point equality in 1d point control
f73292e
to
f1635a2
Compare
Having some issues with convergence when the temperature gets to around 1500K. Not sure yet what is causing the issue yet. Below is the script that I'm currently using to try and march through the flame solutions using the two-point control.
Here's a plot of the history of the main variables. I'm seeing a |
I observed that the ability to get solutions down near the 1000K temperature seems to be dependent on the grid not refining. In this approach the interior control points are located using that set_fuel_side_boundary() method. I'm wondering if during a refinement, we would need to re-call those methods after points have been deleted/added to the domain. |
Having the grid refinement disabled results in a more stable march down the unstable burning branch. Ideally, in the solve() method we would need to re-evaluate the location of the control points at the start of each refinement loop. I see that there's a steady callback that can be called, which is where I would put the calls to method that set the internal boundary locations, but I don't quite understand if that would be something I could do. I don't have any experience with callbacks. |
It doesn't look like you have pushed anything to this branch recently -- the history here says the last time you pushed was July 6. Have you rebased more recently than that? |
I have not. I had noticed that Mr. Schoegl had done some work recently and I was thinking about trying to rebase my changes again against his. I'm just not sure if my previous rebasing is actually being done correctly, so if I'm messing up the commit history in some way, I wanted to see if you could take a look to double-check. |
Some of the (presumably extensive) merge conflicts are due to this PR introducing major code reorganizations in
I can definitely see why you're doing this, but relatively modest changes in That said, I don't believe that hard-coding individual governing equations into separate functions is the way to go any longer. |
Yes. I realized that I polluted the continuation work with residual equation refactoring instead of having them separate. I do have a better grasp on what the original PR was doing, so I believe I can start again with what's in the current branch and make only changes to add that feature. Having the single method to evaluate every equation was a bit overwhelming for me. I was also confused as to why there was an evalRightBoundary method but no corresponding evalLeftBoundary method in StFlow.cpp. |
Agreed. It is overwhelming! My hunch is that this bit of code has survived for this long with relatively small changes due to being overly complex. I hope that this will change eventually ... you may have noticed that I cleaned up the - rather confusing - boundary conditions (apart from locating several hardcoded indices), in a series of incremental steps. On a separate note, we replaced all |
I am also interested in the flame control method in S-curve generation, and adapted the code based on your commit. Basically, I did one improvement: change the setFuelInternalBoundary and setOxidizerInternalBoundary function based on setFixedTemperature function, so that the control point has the exact temperature of provided Tfuel and Toxid, and this point will not be removed. Details of my implementation could be found in my scurve branch. I am more interested in the counterflow premixed flame continuation, and conducted some test cases with my version. The script is based on the version provided above. However, I found the iterations are stucked at a later stage. The temperature does not decrease any more. I may also share a short movie on the temperature change throughout this process. |
Thanks @yeanment . I've been wanting to have a feature like this in Cantera for quite some time now, so any input from others who also share this goal is more than welcome. Getting a feature like this into Cantera in a robust form would be fantastic for expanding the usage of Cantera for flamelet modeling. From my understanding, the method first takes an existing solution, which has a temperature field T(xj), and then a user sets a temperature that they wish to use for locating the control point along the x-axis. We loop through and find the closest points to that desired point and store the location and the temperature. Then the user sets an updated temperature to use at those control points, and the algorithm them solves the governing equations with the two extra equations to drive the temperature at the original control point locations to the new temperature values. In your change, you are taking the original starting temperature field T(xj), and then finding either a point that is sufficient close that it can be considered to the same, or you find the bounding temperature values around the desired value and interpolate to the exact value and insert an extra point into the domain at that location? Would that be a correct summary of your update to the algorithm? There's definitely some issue for when the flame gets strained strongly and becomes very thin, that the points along the flame profile become sparse when solving without grid refinement. I think the trick would be to find a way to make the grid refinement play nice with the control point locator methods. I believe this is the current issue with failure to converge at lower maximum temperatures. |
@wandadars I also want this feature for a long time, but does not have enough time to implement it till recently. Your summary is correct. Can you elaborate your point on " I think the trick would be to find a way to make the grid refinement play nice with the control point locator methods.? From my understanding, one fixed temperature will lead to one specific inlet velocity in the case of premixed counterflow twin flame. In my previous experience on s-curve continuation with arc-length continuation method, the grid does play an important role in getting the results convergent fast. If the arc-length continuation fails, I may change the computational domain or minimal grid size to make the computation continues. But in the flame-control method, I do not know how to make it work. Can you give me some suggestions on this? Besides, I merge the main modification with the recent Cantera master branch. To ensure a minimal change to the original code, I only consider one-point continue, otherwise a lot of tests will fail due to the addition of a new equation. I am not sure if there are some better options in adding additional equations in Cantera without making test failed repeatedly. In my recent implementation, zero gradient is applied to the lambda equation except at the zFuel point (modified in StFlow.cpp). At this position, the fixed temperature boundary condition is imposed and the fixed inlet velocity boundary is thereby released for the left inlet point (modified in Boundary1D.cpp). You may check my recent commit on scurve branch. The code can run continuation. However, when I check the results, I found that the lambda value at the inlet is not the same with that at other points. Do you have any idea on this problem? Below is some representative results. The first is the temperature during continuation. The second is Tmax versus inlet velocity. The third is one result during continuation. Almost everything is the same with your script except I plot the Qdot in Uo subplot since one-point continuation is considered for now. |
@yeanment From my understanding, if we have a set of boundary conditions, and we have an initial condition and a set of control points, the 1D solver sets up the system of equations for the standard governing equations and the Uo and Lamda equations. These last two equations are zero gradient everywhere except where the control points are located. What I meant by playing nice was that the control points are initially located prior to the solver being active. These points are located via a temperature, and in the algorithm here, those points are taken to be the points closest to that reference temperature. During the solution process, the solver may refine the grid and add several points that are closer to the reference temperature value. I'm not sure if this is an issue, but I was wondering if I could make a call to the functions that place the control points between each refinement, if that would improve the stability. As it is currently, if I do not disable grid refinement, the script fails to generate even a moderate number of solutions down the unstable branch, but with refinement disabled, I see that it can get down much closer to the extinction point. I see that in your plots, the flame appears to be very close to the right inlet, and this might be causing issues. You may need to adjust your mass flow rates or domain width. Ideally you want that spike in the temperature field to be near the center of your domain. |
@wandadars That might make a point. But if we do not know how to choose the best one, we cannot make the program choose the best. It's pretty difficult. |
Did you have anything in mind for reorganizing the 1D solver method @ischoegl ? Something like splitting up equations as a set of classes that can be looped over to evaluate? Like an Equation base class and then EnergyEquation, RadialMomentumEquation, ContinuityEquation, and these derived classes would be responsible for providing the residual evaluation at the interior of the domain. It definitely feels like much of the coding has content that is pushed together into large methods. I suppose the separate equation objects approach would cause issues with the boundary objects, because they would need to know which equation they are adjusting. I'm just curious if any major adjustments are being brainstormed for the oneD coding. If large changes aren't coming any time soon, I will re-work the one and two point continuation coding into a smaller pull request without all those other changes that I made to the oneD classes regarding the equations. In the current implementation the fuel boundary is assumed to be on the left and the oxidizer on the right, based on the coding in the Sim1D.cpp file for the setFuelInternalBoundary and setOxidizerInternalBoundary methods. Is generally the case for the setup of the counterflow configurations? |
I have ideas, but I'm not convinced that I have the bandwidth in the near future. It would be nice to add equations dynamically during the setup process, but I am not convinced that there is much of a benefit short-term. If efforts like yours become more frequent (and we start seeing large blocks of 'reserved' but often unused entries) then it may make sense eventually.
There really isn't much of a discussion at the moment. I personally tried to clean up some of the BC's and data entries so they can be 'reused' for extensions I am working on (mostly stuff that works like
There aren't any rules afaik, so fuel and oxidizer can be on either side - it would be good to either generalize or implement checks that users do what the code expects ... |
Work on this is shifted to #1622 |
This pull request is based on the pull request #766.
Changes proposed in this pull request
The original work appears to be based on the method described in the following paper:
https://www.yang.gatech.edu/publications/Journal/C&F%20(2014,%20Huo)%20-%20S%20curve.pdf
Reference information: https://www.sciencedirect.com/science/article/abs/pii/S0010218014001825
The original comments by @speth regarding work that needed to be done with this feature center around numerical stability when using the feature.
I would also like to understand the significance of the Strain Equation option that was present in the original work (#541), and why it was not included in this update of #766. To understand if this has anything to do with the stability issues that are being seen when using the feature in its current form.
Another relevant reference that discusses the governing equations used in the previous reference in more detail is: https://www.sciencedirect.com/science/article/abs/pii/S0010218008001569 so that I can compare with what Cantera uses (https://cantera.org/science/flames.html)