Skip to content

Conversation

@gardner48
Copy link
Member

@gardner48 gardner48 commented Oct 19, 2025

Fix a bug in the CVODE(S) inequality constraint handling where the predicted state was used to compute the step size reduction factor instead of the prior solution which could lead to an incorrect reduction in the step size or, when the prediction violates the constraints, an infinitely large step size in the next step attempt. (Fixes #702)

Add a unit test for inequality constraint handling with all the integrators.

In CVODE(S) and IDA(S), separate inequality constraint check from the nonlinear solve check.

Add functions to set the maximum number of inequality constraint failures and get total number of failures (constraint failures are no longer included in the number of step failures due to a solver failure).

Add a function to get the number of steps modified but not failed due to constraint violations.

Synchronize some differences between CVODE/CVODES and IDA/IDAS source and docs.

Add missing return flag names to CVodeGetReturnFlagName in CVODES and IDAGetReturnFlagName in IDA.

@gardner48 gardner48 requested a review from balos1 as a code owner October 19, 2025 21:23
@gardner48
Copy link
Member Author

@drreynolds I've updated the correction modification to address the roundoff issues and resolved the open comments. However, this PR also includes updates from #788 (makes adding logging to the constraint checks easier), so hold off on taking another pass over this PR until that one is merged.

@gardner48 gardner48 requested a review from drreynolds November 24, 2025 19:27
CVODES options set via :c:func:`CVodeSetOptions` will overwrite
any previously-set values. Options are set in the order they are given in
``argv`` and, if an option with the same prefix appears multiple times in
``argv``, the value of the last occurrence will used.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
``argv``, the value of the last occurrence will used.
``argv``, the value of the last occurrence will be used.

Comment on lines +2477 to +2479
| **CVODE main solver** | |
+-------------------------------------------------+--------------------------------------------+
| Size of CVODE real and integer workspaces | :c:func:`CVodeGetWorkSpace` |
Copy link
Collaborator

Choose a reason for hiding this comment

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

Was it intentional that these were changed from CVODES to CVODE here in the CVODES documentation? If not, here's a suggestion to revert:

Suggested change
| **CVODE main solver** | |
+-------------------------------------------------+--------------------------------------------+
| Size of CVODE real and integer workspaces | :c:func:`CVodeGetWorkSpace` |
| **CVODES main solver** | |
+-------------------------------------------------+--------------------------------------------+
| Size of CVODES real and integer workspaces | :c:func:`CVodeGetWorkSpace` |

Comment on lines +2524 to +2526
| All CVODE integrator statistics | :c:func:`CVodeGetIntegratorStats` |
+-------------------------------------------------+--------------------------------------------+
| CVODE nonlinear solver statistics | :c:func:`CVodeGetNonlinSolvStats` |
Copy link
Collaborator

Choose a reason for hiding this comment

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

As above, if the change from CVODES to CVODE here in the CVODES documentation was unintentional, here's a suggestion to revert:

Suggested change
| All CVODE integrator statistics | :c:func:`CVodeGetIntegratorStats` |
+-------------------------------------------------+--------------------------------------------+
| CVODE nonlinear solver statistics | :c:func:`CVodeGetNonlinSolvStats` |
| All CVODES integrator statistics | :c:func:`CVodeGetIntegratorStats` |
+-------------------------------------------------+--------------------------------------------+
| CVODES nonlinear solver statistics | :c:func:`CVodeGetNonlinSolvStats` |

+--------------------------------------------------------------------+------------------------------------------+
| **Optional output** | **Function name** |
+====================================================================+==========================================+
| Size of IDA real and integer workspace | :c:func:`IDAGetWorkSpace` |
Copy link
Collaborator

Choose a reason for hiding this comment

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

Was this IDAS -> IDA change intentional (here in the IDAS docs)? If not, here's a suggestion to revert:

Suggested change
| Size of IDA real and integer workspace | :c:func:`IDAGetWorkSpace` |
| Size of IDAS real and integer workspace | :c:func:`IDAGetWorkSpace` |

Comment on lines +1715 to +1718
sunfprintf_long(outfile, fmt, SUNFALSE, "Constraint fails",
cv_mem->constraint_fails);
sunfprintf_long(outfile, fmt, SUNFALSE, "Constraint corrections",
cv_mem->constraint_corrections);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you really want to print these by default, or should this be inside a conditional based on whether constraint-handling is used, e.g.

Suggested change
sunfprintf_long(outfile, fmt, SUNFALSE, "Constraint fails",
cv_mem->constraint_fails);
sunfprintf_long(outfile, fmt, SUNFALSE, "Constraint corrections",
cv_mem->constraint_corrections);
if (cv_mem->cv_constraints == NULL)
{
sunfprintf_long(outfile, fmt, SUNFALSE, "Constraint fails",
cv_mem->constraint_fails);
sunfprintf_long(outfile, fmt, SUNFALSE, "Constraint corrections",
cv_mem->constraint_corrections);
}

(and similar question for CVODES, IDA, and IDAS)

Comment on lines +2616 to +2619
sunfprintf_long(outfile, fmt, SUNFALSE, "Constraint fails",
cv_mem->constraint_fails);
sunfprintf_long(outfile, fmt, SUNFALSE, "Constraint corrections",
cv_mem->constraint_corrections);
Copy link
Collaborator

Choose a reason for hiding this comment

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

As with CVODE, do you really want to print these by default?

Comment on lines +1496 to +1499
sunfprintf_long(outfile, fmt, SUNFALSE, "Constraint fails",
IDA_mem->constraint_fails);
sunfprintf_long(outfile, fmt, SUNFALSE, "Constraint corrections",
IDA_mem->constraint_corrections);
Copy link
Collaborator

Choose a reason for hiding this comment

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

As with CVODE, do you really want to print these by default?

Comment on lines +2323 to +2326
sunfprintf_long(outfile, fmt, SUNFALSE, "Constraint fails",
IDA_mem->constraint_fails);
sunfprintf_long(outfile, fmt, SUNFALSE, "Constraint corrections",
IDA_mem->constraint_corrections);
Copy link
Collaborator

Choose a reason for hiding this comment

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

As with CVODE, do you really want to print these by default?

if ((SUNRabs(cv_mem->cv_h) <= cv_mem->cv_hmin * ONEPSM) ||
(*step_constraint_fails == cv_mem->max_constraint_fails))
{
SUNLogInfo(CV_LOGGER, "end-constraint-check", "status = failed max attempts");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Minor item: this error message could also be displayed if |h|==hmin, so couldn't this "status" be misleading? The same comment is relevant for CVODES, IDA, and IDAS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants