Setting a custom predictor in the generalized-alpha time stepper
Hi, My understanding is that the second-order generalized-alpha time stepper in PETSc uses a same-displacement predictor as the initial guess for the nonlinear solver that executes in each time step. I'd like to be able to set this to something else, to improve convergence. However, my (possibly-naive) attempts to use `TSSetPreStep` and `TSSetPreStage` haven't worked out. Is there any way to set a custom predictor? Thanks, David Kamensky
I think you can use TSGetSNES() and SNESSetComputeInitialGuess() to modify the initial guess for SNES. Would that serve your needs? Is there anything else you can say about how you'd like to compute this initial guess? Is there a paper or something? David Kamensky <[email protected]> writes:
Hi,
My understanding is that the second-order generalized-alpha time stepper in PETSc uses a same-displacement predictor as the initial guess for the nonlinear solver that executes in each time step. I'd like to be able to set this to something else, to improve convergence. However, my (possibly-naive) attempts to use `TSSetPreStep` and `TSSetPreStage` haven't worked out. Is there any way to set a custom predictor?
Thanks, David Kamensky
Hi Jed, What I'm trying to compute is basically a standard same-velocity or same-acceleration predictor (although slightly more complicated, since I'm restricting it to a sub-system). I hadn't looked into `SNESSetComputeInitialGuess` yet, although one difficulty is that it would need access to the `X0`, `V0`, and `A0` members of the `TS_Alpha` struct, which is only defined in `alpha2.c`, and thus not available through the API. For now, we just worked around this by patching PETSc to move the definition of `TS_Alpha` up into a header to make it accessible. (Modifying the library obviously introduces a maintenance headache; I also considered just casting the `ts->data` pointer to `(char*)`, calculating memory offsets based on `sizeof` the struct members, and casting back to `Vec`, but that relies on compiler-specific assumptions, and could also break if the PETSc source code was updated.) We also shuffled the order of some calls to `VecCopy` and `TSPreStage` in the routine `TSAlpha_Restart`, so that `TSPreStage` can set the initial guess, although that sounds like it would be unnecessary if we instead used a callback in `SNESSetComputeInitialGuess` that had access to the internals of `TS_Alpha`. Thanks, David On Thu, Aug 3, 2023 at 11:28 PM Jed Brown <[email protected]> wrote:
I think you can use TSGetSNES() and SNESSetComputeInitialGuess() to modify the initial guess for SNES. Would that serve your needs? Is there anything else you can say about how you'd like to compute this initial guess? Is there a paper or something?
David Kamensky <[email protected]> writes:
Hi,
My understanding is that the second-order generalized-alpha time stepper in PETSc uses a same-displacement predictor as the initial guess for the nonlinear solver that executes in each time step. I'd like to be able to set this to something else, to improve convergence. However, my (possibly-naive) attempts to use `TSSetPreStep` and `TSSetPreStage` haven't worked out. Is there any way to set a custom predictor?
Thanks, David Kamensky
Some other TS implementations have a concept of extrapolation as an initial guess. Such method-specific initial guesses sound like they fit that pattern and would be welcome to be included in alpha2.c. Would you be willing to make a merge request to bring your work upstream? David Kamensky <[email protected]> writes:
Hi Jed,
What I'm trying to compute is basically a standard same-velocity or same-acceleration predictor (although slightly more complicated, since I'm restricting it to a sub-system). I hadn't looked into `SNESSetComputeInitialGuess` yet, although one difficulty is that it would need access to the `X0`, `V0`, and `A0` members of the `TS_Alpha` struct, which is only defined in `alpha2.c`, and thus not available through the API.
For now, we just worked around this by patching PETSc to move the definition of `TS_Alpha` up into a header to make it accessible. (Modifying the library obviously introduces a maintenance headache; I also considered just casting the `ts->data` pointer to `(char*)`, calculating memory offsets based on `sizeof` the struct members, and casting back to `Vec`, but that relies on compiler-specific assumptions, and could also break if the PETSc source code was updated.) We also shuffled the order of some calls to `VecCopy` and `TSPreStage` in the routine `TSAlpha_Restart`, so that `TSPreStage` can set the initial guess, although that sounds like it would be unnecessary if we instead used a callback in `SNESSetComputeInitialGuess` that had access to the internals of `TS_Alpha`.
Thanks, David
On Thu, Aug 3, 2023 at 11:28 PM Jed Brown <[email protected]> wrote:
I think you can use TSGetSNES() and SNESSetComputeInitialGuess() to modify the initial guess for SNES. Would that serve your needs? Is there anything else you can say about how you'd like to compute this initial guess? Is there a paper or something?
David Kamensky <[email protected]> writes:
Hi,
My understanding is that the second-order generalized-alpha time stepper in PETSc uses a same-displacement predictor as the initial guess for the nonlinear solver that executes in each time step. I'd like to be able to set this to something else, to improve convergence. However, my (possibly-naive) attempts to use `TSSetPreStep` and `TSSetPreStage` haven't worked out. Is there any way to set a custom predictor?
Thanks, David Kamensky
Hi Jed, The current workaround I'm using is very minimal and basically just moves the definition of `TS_Alpha` from `alpha2.c` up to `petsc/private/tsimpl.h` (and renames it to avoid a conflict with `TS_Alpha` in `alpha1.c`), but I gather that we're really still not "supposed to" include that header in applications. So, I don't know whether something like that would be welcomed upstream. The actual computation of the predictor is done on the application side. Having options like `-ts_alpha_same_velocity` and `-ts_alpha_same_acceleration` could probably be implemented by analogy to `-ts_theta_initial_guess_extrapolate`, although they wouldn't quite cover my specific use-case, where I'm only setting the predictor on part of the solution vector. So, maybe something more general, like providing a generalized-$\alpha$-specific option for a custom predictor callback that takes `X0`, `V0`, and `A0` arguments would be the cleanest solution (and some convenient shortcuts for full-solution same-velocity and same-acceleration predictors could subsequently make use of that infrastructure). I've been working quickly over the past week, but I might be able to take some time to implement a more sustainable solution soon. Thanks again, David On Fri, Aug 4, 2023 at 9:23 AM Jed Brown <[email protected]> wrote:
Some other TS implementations have a concept of extrapolation as an initial guess. Such method-specific initial guesses sound like they fit that pattern and would be welcome to be included in alpha2.c. Would you be willing to make a merge request to bring your work upstream?
David Kamensky <[email protected]> writes:
Hi Jed,
What I'm trying to compute is basically a standard same-velocity or same-acceleration predictor (although slightly more complicated, since I'm restricting it to a sub-system). I hadn't looked into `SNESSetComputeInitialGuess` yet, although one difficulty is that it would need access to the `X0`, `V0`, and `A0` members of the `TS_Alpha` struct, which is only defined in `alpha2.c`, and thus not available through the API.
For now, we just worked around this by patching PETSc to move the definition of `TS_Alpha` up into a header to make it accessible. (Modifying the library obviously introduces a maintenance headache; I also considered just casting the `ts->data` pointer to `(char*)`, calculating memory offsets based on `sizeof` the struct members, and casting back to `Vec`, but that relies on compiler-specific assumptions, and could also break if the PETSc source code was updated.) We also shuffled the order of some calls to `VecCopy` and `TSPreStage` in the routine `TSAlpha_Restart`, so that `TSPreStage` can set the initial guess, although that sounds like it would be unnecessary if we instead used a callback in `SNESSetComputeInitialGuess` that had access to the internals of `TS_Alpha`.
Thanks, David
On Thu, Aug 3, 2023 at 11:28 PM Jed Brown <[email protected]> wrote:
I think you can use TSGetSNES() and SNESSetComputeInitialGuess() to modify the initial guess for SNES. Would that serve your needs? Is there anything else you can say about how you'd like to compute this initial guess? Is there a paper or something?
David Kamensky <[email protected]> writes:
Hi,
My understanding is that the second-order generalized-alpha time stepper in PETSc uses a same-displacement predictor as the initial guess for the nonlinear solver that executes in each time step. I'd like to be able to set this to something else, to improve convergence. However, my (possibly-naive) attempts to use `TSSetPreStep` and `TSSetPreStage` haven't worked out. Is there any way to set a custom predictor?
Thanks, David Kamensky
Yeah, we'd like the implementation to stay in alpha2.c. There could be a new interface TSAlpha2SetPredictorType (with -ts_alpha2_predictor_type [none,same_velocity,...]) or TSAlpha2SetPredictorFunction. David Kamensky <[email protected]> writes:
Hi Jed,
The current workaround I'm using is very minimal and basically just moves the definition of `TS_Alpha` from `alpha2.c` up to `petsc/private/tsimpl.h` (and renames it to avoid a conflict with `TS_Alpha` in `alpha1.c`), but I gather that we're really still not "supposed to" include that header in applications. So, I don't know whether something like that would be welcomed upstream. The actual computation of the predictor is done on the application side.
Having options like `-ts_alpha_same_velocity` and `-ts_alpha_same_acceleration` could probably be implemented by analogy to `-ts_theta_initial_guess_extrapolate`, although they wouldn't quite cover my specific use-case, where I'm only setting the predictor on part of the solution vector. So, maybe something more general, like providing a generalized-$\alpha$-specific option for a custom predictor callback that takes `X0`, `V0`, and `A0` arguments would be the cleanest solution (and some convenient shortcuts for full-solution same-velocity and same-acceleration predictors could subsequently make use of that infrastructure). I've been working quickly over the past week, but I might be able to take some time to implement a more sustainable solution soon.
Thanks again, David
On Fri, Aug 4, 2023 at 9:23 AM Jed Brown <[email protected]> wrote:
Some other TS implementations have a concept of extrapolation as an initial guess. Such method-specific initial guesses sound like they fit that pattern and would be welcome to be included in alpha2.c. Would you be willing to make a merge request to bring your work upstream?
David Kamensky <[email protected]> writes:
Hi Jed,
What I'm trying to compute is basically a standard same-velocity or same-acceleration predictor (although slightly more complicated, since I'm restricting it to a sub-system). I hadn't looked into `SNESSetComputeInitialGuess` yet, although one difficulty is that it would need access to the `X0`, `V0`, and `A0` members of the `TS_Alpha` struct, which is only defined in `alpha2.c`, and thus not available through the API.
For now, we just worked around this by patching PETSc to move the definition of `TS_Alpha` up into a header to make it accessible. (Modifying the library obviously introduces a maintenance headache; I also considered just casting the `ts->data` pointer to `(char*)`, calculating memory offsets based on `sizeof` the struct members, and casting back to `Vec`, but that relies on compiler-specific assumptions, and could also break if the PETSc source code was updated.) We also shuffled the order of some calls to `VecCopy` and `TSPreStage` in the routine `TSAlpha_Restart`, so that `TSPreStage` can set the initial guess, although that sounds like it would be unnecessary if we instead used a callback in `SNESSetComputeInitialGuess` that had access to the internals of `TS_Alpha`.
Thanks, David
On Thu, Aug 3, 2023 at 11:28 PM Jed Brown <[email protected]> wrote:
I think you can use TSGetSNES() and SNESSetComputeInitialGuess() to modify the initial guess for SNES. Would that serve your needs? Is there anything else you can say about how you'd like to compute this initial guess? Is there a paper or something?
David Kamensky <[email protected]> writes:
Hi,
My understanding is that the second-order generalized-alpha time stepper in PETSc uses a same-displacement predictor as the initial guess for the nonlinear solver that executes in each time step. I'd like to be able to set this to something else, to improve convergence. However, my (possibly-naive) attempts to use `TSSetPreStep` and `TSSetPreStage` haven't worked out. Is there any way to set a custom predictor?
Thanks, David Kamensky
If you want to make a PR with your hack, we can help build out the infrastructure for what Jed is recommending. Thanks, Matt On Fri, Aug 4, 2023 at 2:56 PM Jed Brown <[email protected]> wrote:
Yeah, we'd like the implementation to stay in alpha2.c. There could be a new interface TSAlpha2SetPredictorType (with -ts_alpha2_predictor_type [none,same_velocity,...]) or TSAlpha2SetPredictorFunction.
David Kamensky <[email protected]> writes:
Hi Jed,
The current workaround I'm using is very minimal and basically just moves the definition of `TS_Alpha` from `alpha2.c` up to `petsc/private/tsimpl.h` (and renames it to avoid a conflict with `TS_Alpha` in `alpha1.c`), but I gather that we're really still not "supposed to" include that header in applications. So, I don't know whether something like that would be welcomed upstream. The actual computation of the predictor is done on the application side.
Having options like `-ts_alpha_same_velocity` and `-ts_alpha_same_acceleration` could probably be implemented by analogy to `-ts_theta_initial_guess_extrapolate`, although they wouldn't quite cover my specific use-case, where I'm only setting the predictor on part of the solution vector. So, maybe something more general, like providing a generalized-$\alpha$-specific option for a custom predictor callback that takes `X0`, `V0`, and `A0` arguments would be the cleanest solution (and some convenient shortcuts for full-solution same-velocity and same-acceleration predictors could subsequently make use of that infrastructure). I've been working quickly over the past week, but I might be able to take some time to implement a more sustainable solution soon.
Thanks again, David
On Fri, Aug 4, 2023 at 9:23 AM Jed Brown <[email protected]> wrote:
Some other TS implementations have a concept of extrapolation as an initial guess. Such method-specific initial guesses sound like they fit that pattern and would be welcome to be included in alpha2.c. Would you be willing to make a merge request to bring your work upstream?
David Kamensky <[email protected]> writes:
Hi Jed,
What I'm trying to compute is basically a standard same-velocity or same-acceleration predictor (although slightly more complicated, since I'm restricting it to a sub-system). I hadn't looked into `SNESSetComputeInitialGuess` yet, although one difficulty is that it would need access to the `X0`, `V0`, and `A0` members of the `TS_Alpha` struct, which is only defined in `alpha2.c`, and thus not available through the API.
For now, we just worked around this by patching PETSc to move the definition of `TS_Alpha` up into a header to make it accessible. (Modifying the library obviously introduces a maintenance headache; I also considered just casting the `ts->data` pointer to `(char*)`, calculating memory offsets based on `sizeof` the struct members, and casting back to `Vec`, but that relies on compiler-specific assumptions, and could also break if the PETSc source code was updated.) We also shuffled the order of some calls to `VecCopy` and `TSPreStage` in the routine `TSAlpha_Restart`, so that `TSPreStage` can set the initial guess, although that sounds like it would be unnecessary if we instead used a callback in `SNESSetComputeInitialGuess` that had access to the internals of `TS_Alpha`.
Thanks, David
On Thu, Aug 3, 2023 at 11:28 PM Jed Brown <[email protected]> wrote:
I think you can use TSGetSNES() and SNESSetComputeInitialGuess() to modify the initial guess for SNES. Would that serve your needs? Is there anything else you can say about how you'd like to compute this initial guess? Is there a paper or something?
David Kamensky <[email protected]> writes:
Hi,
My understanding is that the second-order generalized-alpha time stepper in PETSc uses a same-displacement predictor as the initial guess for the nonlinear solver that executes in each time step. I'd like to be able to set this to something else, to improve convergence. However, my (possibly-naive) attempts to use `TSSetPreStep` and `TSSetPreStage` haven't worked out. Is there any way to set a custom predictor?
Thanks, David Kamensky
-- What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead. -- Norbert Wiener https://www.cse.buffalo.edu/~knepley/ <http://www.cse.buffalo.edu/~knepley/>
participants (3)
-
David Kamensky -
Jed Brown -
Matthew Knepley