!
!  Tests MatGetNullSpace() and PetscObjectIsNull()
!
#include <petsc/finclude/petscmat.h>
program main

  use petscmat
  implicit none

  PetscErrorCode ierr
  Mat A, B
  Mat C, SC
  MatNullSpace sp, sp1
  PetscInt rend
  PetscScalar, parameter :: sone = 1.0
  Vec x, y

  PetscCallA(PetscInitialize(ierr))

  PetscCallA(MatCreate(PETSC_COMM_WORLD, A, ierr))
  PetscCallA(MatCreate(PETSC_COMM_WORLD, B, ierr))

  PetscCallA(MatGetNullSpace(A, sp, ierr))
  PetscCheckA(PetscObjectIsNull(sp), PETSC_COMM_SELF, PETSC_ERR_PLIB, 'Matrix null space should not exist')

  PetscCallA(MatSetNullSpace(A, PETSC_NULL_MATNULLSPACE, ierr))
  PetscCallA(MatGetNullSpace(A, sp, ierr))
  PetscCheckA(PetscObjectIsNull(sp), PETSC_COMM_SELF, PETSC_ERR_PLIB, 'Matrix null space should not exist')

  PetscCallA(MatNullSpaceCreate(PETSC_COMM_WORLD, PETSC_TRUE, 0_PETSC_INT_KIND, PETSC_NULL_VEC_ARRAY, sp, ierr))
  PetscCallA(MatSetNullSpace(A, sp, ierr))
  PetscCallA(MatGetNullSpace(A, sp1, ierr))
  PetscCheckA(.not. PetscObjectIsNull(sp), PETSC_COMM_SELF, PETSC_ERR_PLIB, 'Matrix null space should not exist')
  PetscCallA(MatNullSpaceDestroy(sp, ierr))

  PetscCallA(MatCreateSeqDense(PETSC_COMM_WORLD, 1_PETSC_INT_KIND, 1_PETSC_INT_KIND, PETSC_NULL_SCALAR_ARRAY, C, ierr))
  PetscCallA(MatSetValues(C, 1_PETSC_INT_KIND, [0_PETSC_INT_KIND], 1_PETSC_INT_KIND, [0_PETSC_INT_KIND], [sone], INSERT_VALUES, ierr))
  PetscCallA(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY, ierr))
  PetscCallA(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY, ierr))
  PetscCallA(MatCreateSchurComplement(C, C, C, C, PETSC_NULL_MAT, SC, ierr))
  PetscCallA(MatGetOwnershipRange(SC, PETSC_NULL_INTEGER, rend, ierr))
  PetscCallA(VecCreateSeq(PETSC_COMM_SELF, 1_PETSC_INT_KIND, x, ierr))
  PetscCallA(VecDuplicate(x, y, ierr))
  PetscCallA(VecSetValues(x, 1_PETSC_INT_KIND, [0_PETSC_INT_KIND], [sone], INSERT_VALUES, ierr))
  PetscCallA(VecAssemblyBegin(x, ierr))
  PetscCallA(VecAssemblyEnd(x, ierr))
  PetscCallA(MatMult(SC, x, y, ierr))
  PetscCallA(VecView(y, PETSC_VIEWER_STDOUT_SELF, ierr))
  PetscCallA(VecSetRandom(x, PETSC_NULL_RANDOM, ierr))
  PetscCallA(VecView(x, PETSC_VIEWER_STDOUT_SELF, ierr))

  PetscCallA(MatDestroy(SC, ierr))
  PetscCallA(MatDestroy(C, ierr))
  PetscCallA(VecDestroy(x, ierr))
  PetscCallA(VecDestroy(y, ierr))
  PetscCallA(MatDestroy(A, ierr))
  PetscCallA(MatDestroy(B, ierr))
  PetscCallA(PetscFinalize(ierr))
end

!/*TEST
!
!   test:
!      requires: !complex
!
!TEST*/
