[petsc-users] SNES_QN_RESTART_POWELL fails to converge?
Andrew Ho
andrewh0 at uw.edu
Thu Jul 14 18:28:38 CDT 2016
On Thu, Jul 14, 2016 at 4:22 PM, Matthew Knepley <knepley at gmail.com> wrote:
> On Thu, Jul 14, 2016 at 6:18 PM, Andrew Ho <andrewh0 at uw.edu> wrote:
>
>> I am trying to solve a simple ionization/recombination ODE using PETSc's
>> quasi-newton SNES.
>>
>> This is a basic non-linear coupled ODE system:
>>
>> delta = -a u^2 + b u v
>> d_t u = delta
>> d_t v = -delta
>>
>> a and b are constants.
>>
>> I wrote a backwards Euler root finding function (yes, I know the TS
>> module has BE implemented, but this is more of a learning exercise).
>>
>> Here is the function evaluation:
>>
>> struct ion_rec_ctx
>>> {
>>> PetscScalar rate_a, rate_b;
>>> PetscScalar dt;
>>> };
>>> PetscErrorCode bdf1(SNES snes, Vec x, Vec f, void *ctx)
>>> {
>>> const PetscScalar *xx;
>>> PetscScalar *ff;
>>> ion_rec_ctx& params = *reinterpret_cast<ion_rec_ctx*>(ctx);
>>> CHKERRQ(VecGetArrayRead(x, &xx));
>>> CHKERRQ(VecGetArray(f,&ff));
>>> auto delta = (-params.rate_a*xx[0]*xx[0]+params.rate_b*xx[1]*xx[0]);
>>> ff[0] = xx[0]-params.dt*delta;
>>>
>>
> I do not understand this. Shouldn't it be (xx[0] - xxold[0]) here?
>
> Matt
>
No, the time discretization is as such:
xnew = xold + dt*f(xnew)
I re-arrange this to be
xnew - dt*f(xnew) = xold
The left hand side I am defining as g(x), which is what the bdf1 function
evaluates. The SNES module solves for g(x) = b, so I simply set b = xold.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20160714/f8e40aa8/attachment-0001.html>
More information about the petsc-users
mailing list