-
Notifications
You must be signed in to change notification settings - Fork 90
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
CVODE constraints and max_noinlinear_iterations options #2303
Conversation
Uses CVodeSetConstraints function to allow constraints to be applied to variables to be: none (default, no constraint), positive, non_negative, negative, or non_positive.
1ae1da1
to
cf1ce5a
Compare
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.
clang-tidy made some suggestions
// Loop over 2D variables | ||
for (std::vector<BoutReal>::size_type i = 0; i < f2dtols.size(); i++) { | ||
if (bndry && !f2d[i].evolve_bndry) { | ||
continue; | ||
} | ||
abstolvec_data[p] = f2dtols[i]; | ||
option_data[p] = f2dtols[i]; |
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.
warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]
option_data[p] = f2dtols[i];
^
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.
Don't understand this error - I don't think there's any pointer arithmetic here, just accessing a C-array with an int
index...
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 C-array indexing is basically sugar for pointer arithmetic: the compiler turns it into *(option_data + p) = f2dtols[i]
(and this is why array[0] == 0[array]
works even though it looks like bad magic). This is a bit more obvious looking at the function signature, which takes a BoutReal*
rather than an array type.
There isn't a great deal we can do to do this properly, given that we don't own N_Vector
(and also that it's pretty much an opaque pointer). In C++20, we could take a std::span
here instead of BoutReal*
.
I think we could use N_VMake_Parallel
to create abstolvec
with our own data (e.g. Array
), and then pass that directly to set_abstol_values
.
(Incidentally, I'm pretty sure we could do something like that to avoid copying the derivatives in and out of the solver's data structures if we could somehow allocate a big block of consecutive memory for the derivatives in the first place)
@@ -686,7 +776,7 @@ void CvodeSolver::loop_abstol_values_op(Ind2D UNUSED(i2d), BoutReal* abstolvec_d | |||
if (bndry && !f3d[i].evolve_bndry) { | |||
continue; | |||
} | |||
abstolvec_data[p] = f3dtols[i]; | |||
option_data[p] = f3dtols[i]; |
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.
warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]
option_data[p] = f3dtols[i];
^
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.
LGTM, maybe a couple of things to polish
Reduces code duplication.
Interface to two more options provided by CVODE solver:
solver:apply_positivity_constraints
- if set to true, read an optionpositivity_constraint
in each variable subsection, which can be set tonone
(the default),positive
,non_negative
,negative
, ornon_positive
. If any of these constraints is violated at the end of an internal timestep, CVODE will go back to the previous step and continue with a shorter timestep.solver:max_nonlinear_iterations
- allow changing the maximum number of nonlinear iterations allowed for each timestep. CVODE default is 3. Might be useful to increase if the number of linear iterations per Newton iteration is small, but a very brief test did not observe any benefit.