Skip to content
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

Simplify/Fix Adaptivity for Small Errors or no CFL #548

Open
wants to merge 71 commits into
base: develop
Choose a base branch
from

Conversation

Steven-Roberts
Copy link
Collaborator

The TINY parameter used in the controllers could cause an error overestimation, particularly for the first step.

Copy link
Collaborator

@drreynolds drreynolds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not expert on how robustly various architectures/compilers work with infinity. I'd like to see this PR pass all possible regression tests on all architectures before approving, but if infinity is handled correctly everywhere, then I would approve of these changes.

As another option, we could use the largest/smallest representable floating point numbers in the given precision to avoid having to do arithmetic with infinity.

@Steven-Roberts
Copy link
Collaborator Author

The behavior of pow, abs, min, max, and other functions for inf/nan is specified by the C standard, so I'm not too worried about that. I think a unit test where the error is 0 is warranted to double check. The standard only specifies that pow(0, 0) may cause a domain error (and doesn't even specify what the value could be), and pow(0, y) can cause floating point exceptions for certain y. I think I'll need to handle that more carefully in the controller.

@Steven-Roberts
Copy link
Collaborator Author

After considering the edge cases around pow(0,0), i.e., when there's no local error and a controller exponent is 0, it turns out to be benign. The C standard specifies pow(x,0)=1 for all x, and there's no undefined behavior. The test I added seems to support this for some limited cases.

}
else
{
*hnew = h * SUNRpowerR(e1, k1) * SUNRpowerR(e2, k2) * SUNRpowerR(e3, k3) *
SUNRpowerR(hrat, k4) * SUNRpowerR(hrat2, k5);
/* Use an I controller on the first two steps */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a PI controller should this use the I controller only for the first step?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be ideal, but I tried to balance that with how many conditions I need to check at every time step, i.e. k3==0 && k4 == 0 && k5 == 0. I can make this change if you think it's worth it. A longer-term change I would recommend is making the error and step histories arrays of exactly the right length rather than fixed $k1$ to $k5$. Then simpler controllers like I don't have to do extra checks and operations on unused k values.

Copy link
Member

@gardner48 gardner48 Feb 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of checking the k values every time maybe the condition if (SODERLIND_FIRSTSTEPS(C) > 1) could swap 1 for a parameter that's set at construction (or when the parameter values are updated) i.e., it would be -1 for an I controller, 0 for a PI controller, and 1 for a PID controller.

@@ -1,3 +1,7 @@
[ERROR][rank 0][/var/lib/jenkins/workspace/SUNDIALS_PR-548/test/tarballs/sundials-7.2.1/src/arkode/arkode.c:824][ARKodeEvolve] At t = 0.808058307775222, mxstep steps taken before reaching tout.

SUNDIALS_ERROR: ARKodeEvolve() failed with flag = -1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example fails after the changes. Not sure why it still prints the output below, maybe a return statement is missing

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't replicate this locally, so I increased the max step limit so it will at least finish the Jenkins test and we can examine the full out file stats. I think it's just a case of the limit being very close to the actual number of steps taken, and these changes pushed it slightly over.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants