Date: 2025-03-29T05:58:41+00:00

Actual source code: ex40f90.F90

      1: !
      2: !  Demonstrates use of DMDASNESSetFunctionLocal() from Fortran
      3: !
      4: !    Note: the access to the entries of the local arrays below use the Fortran
      5: !   convention of starting at zero. However calls to MatSetValues()  start at 0.
      6: !   Also note that you will have to map the i,j,k coordinates to the local PETSc ordering
      7: !   before calling MatSetValuesLocal(). Often you will find that using PETSc's default
      8: !   code for computing the Jacobian works fine and you will not need to implement
      9: !   your own FormJacobianLocal().

     11:       program ex40f90
     12: #include <petsc/finclude/petscsnes.h>
     13: #include <petsc/finclude/petscdmda.h>
     14:       use petscdmda
     15:       use petscsnes
     16:       implicit none

     18:       SNES             snes
     19:       PetscErrorCode   ierr
     20:       DM               da
     21:       PetscInt         ten,two,one
     22:       PetscScalar      sone
     23:       Vec              x
     24:       external         FormFunctionLocal

     26:       PetscCallA(PetscInitialize(ierr))
     27:       ten = 10
     28:       one = 1
     29:       two = 2
     30:       sone = 1.0

     32:       PetscCallA(DMDACreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_BOX,ten,ten,PETSC_DECIDE,PETSC_DECIDE,two,one,PETSC_NULL_INTEGER_ARRAY,PETSC_NULL_INTEGER_ARRAY,da,ierr))
     33:       PetscCallA(DMSetFromOptions(da,ierr))
     34:       PetscCallA(DMSetUp(da,ierr))

     36: !       Create solver object and associate it with the unknowns (on the grid)

     38:       PetscCallA(SNESCreate(PETSC_COMM_WORLD,snes,ierr))
     39:       PetscCallA(SNESSetDM(snes,da,ierr))

     41:       PetscCallA(DMDASNESSetFunctionLocal(da,INSERT_VALUES,FormFunctionLocal,0,ierr))
     42:       PetscCallA(SNESSetFromOptions(snes,ierr))

     44: !      Solve the nonlinear system
     45: !
     46:       PetscCallA(DMCreateGlobalVector(da,x,ierr))
     47:       PetscCallA(VecSet(x,sone,ierr))
     48:       PetscCallA(SNESSolve(snes,PETSC_NULL_VEC,x,ierr))

     50:       PetscCallA(VecDestroy(x,ierr))
     51:       PetscCallA(SNESDestroy(snes,ierr))
     52:       PetscCallA(DMDestroy(da,ierr))
     53:       PetscCallA(PetscFinalize(ierr))
     54:       end

     56:       subroutine FormFunctionLocal(in,x,f,dummy,ierr)
     57:       use petscdmda
     58:       implicit none
     59:       PetscInt i,j,k,dummy
     60:       DMDALocalInfo in
     61:       PetscScalar x(in%DOF,in%GXS+1:in%GXS+in%GXM,in%GYS+1:in%GYS+in%GYM)
     62:       PetscScalar f(in%DOF,in%XS+1:in%XS+in%XM,in%YS+1:in%YS+in%YM)
     63:       PetscErrorCode ierr

     65:       do i=in%XS+1,in%XS+in%XM
     66:          do j=in%YS+1,in%YS+in%YM
     67:             do k=1,in%DOF
     68:                f(k,i,j) = x(k,i,j)*x(k,i,j) - 2.0
     69:             enddo
     70:          enddo
     71:       enddo

     73:       end

     75: !/*TEST
     76: !
     77: !   test:
     78: !     args: -snes_monitor_short -snes_view -da_refine 1 -pc_type mg -pc_mg_type full -ksp_type fgmres -pc_mg_galerkin pmat
     79: !     requires: !single
     80: !
     81: !TEST*/