> On Nov 4, 2018, at 8:45 AM, Yingjie Wu via petsc-users 
> <[email protected]> wrote:
> 
> Dear Petsc developer:
> Hi,
> Recently, I am very interested in the ex19 example in SNES, which uses NGS 
> method to solve the non-linear equations, which may be the method I need to 
> use in the future. I have some doubts about the program. 
> 1.
> 82: typedef struct {
> 83:   PetscScalar u,v,omega,temp;
> 84: } Field
> 86: PetscErrorCode FormFunctionLocal(DMDALocalInfo*,Field**,Field**,void*);
> …
> 150:   DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode 
> (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,&user);
> 
> I looked at PETSc manualpage: 
> For PetscErrorCode (*func)(DMDALocalInfo *info,void *x, void *f, void *ctx),
> info  - DMDALocalInfo defining the subdomain to evaluate the residual on
> x     - dimensional pointer to state at which to evaluate residual (e.g. 
> PetscScalar *x or **x or ***x)
> f     - dimensional pointer to residual, write the residual here (e.g. 
> PetscScalar *f or **f or ***f)
> ctx   - optional context passed above
> In the function FormFunctionLocal, the second and third parameters should be 
> pointers to PetscScalar, where pointers are directly used to point to Field. 
> Why can we use them here?            Although I know that there are four 
> degrees of freedom in DM objects, how can I ensure that the program correctly 
> corresponds to variables in Field? 
> 
> 2.
> In the NGS subroutine, 
> 530: dfudu = 2.0* (hydhx + hxdhy);            
> But in the residual function:            
> 526: u = x[j][i].u;            
> 527: uxx = (2.0*u - x[j][i-1].u - x[j][i+1].u) *hydhx;            
> 528: uyy = (2.0*u - x[j-1][i].u - x[j+1][i].u) *hxdhy;            
> 529: Fu = uxx + uyy -.5* (x[j+1][i].omega-x[j-1][i].omega) *hx - bjiu;        
>     
> / * invert the system:           
> 572:              [ dfu / du     0        0        0    ][yu] = [fu]
> 573:              [     0    dfv / dv     0        0    ][yv]   [fv]
> 574:              [ dfo / du dfo / dv dfo / do     0    ][yo]   [fo]
> 575:              [ dft / du dft / dv     0    dft / dt ][yt]   [ft]
> 576:              by simple back-substitution         
> 577: * / 
> It is known that the residual function fu [j] [i] is a function of five 
> variables (x [j] [i].u, x [j] [i-1].u, x [j] [i+1].u, x [j-1] [i].u, x [j+1] 
> [i] [i].u) (it is same for analytic Jacobian matrix). But in this program, 
> only the central grid is used to solve the partial derivatives. Why do we 
> choose to do so?            In my understanding, the sub-matrix 'dfudu' is a 
> five-diagonal matrix, but it is processed into a diagonal matrix in the 
> program. Will this affect the accuracy of the solution? 

   NonlinearGS() does iterations of point-block nonlinear Gauss-Seidel (which 
is used as the smoother for nonlinear multigrid). Thus at each grid point it 
does Newton's method (this is the inner loop for (l = 0; l < max_its && 
!ptconverged; l++) {).   In nonlinear Gauss-Seidel smoothing only the diagonal 
block of the Jacobian is needed, the off diagonal block are never needed.

   Barry

> 
> Thanks for your continuous help,
> Yingjie

Reply via email to