Actual source code: ex53.c

  1: static const char help[] = "Tests VecShift()\n\n";

  3: #include <petscvec.h>

  5: static PetscErrorCode CheckVecShift(Vec v, PetscInt n, PetscScalar *array_copy, PetscScalar shift)
  6: {
  7:   const PetscScalar *array;

  9:   PetscFunctionBegin;
 10:   for (PetscInt i = 0; i < n; ++i) array_copy[i] += shift;
 11:   PetscCall(VecShift(v, shift));
 12:   PetscCall(VecGetArrayRead(v, &array));
 13:   for (PetscInt i = 0; i < n; ++i) {
 14:     const PetscScalar actual = array[i], expected = array_copy[i];

 16:     PetscCheck(PetscIsCloseAtTolScalar(actual, expected, 1e-12, 0.0), PETSC_COMM_SELF, PETSC_ERR_PLIB, "VecShift() returned array[%" PetscInt_FMT "] %g + %gi != expected_array[%" PetscInt_FMT "] %g + %gi", i, (double)PetscRealPart(actual), (double)PetscImaginaryPart(actual), i, (double)PetscRealPart(expected), (double)PetscImaginaryPart(expected));
 17:   }
 18:   PetscCall(VecRestoreArrayRead(v, &array));
 19:   PetscFunctionReturn(PETSC_SUCCESS);
 20: }

 22: int main(int argc, char **argv)
 23: {
 24:   Vec                x;
 25:   PetscInt           n;
 26:   const PetscScalar *array;
 27:   PetscScalar       *array_copy;
 28:   PetscReal          norm_before, norm_after;
 29:   PetscBool          available;

 31:   PetscFunctionBeginUser;
 32:   PetscCall(PetscInitialize(&argc, &argv, NULL, help));

 34:   PetscCall(VecCreate(PETSC_COMM_WORLD, &x));
 35:   PetscCall(VecSetSizes(x, PETSC_DECIDE, 10));
 36:   PetscCall(VecSetFromOptions(x));

 38:   // get a copy of the vectors array, anything we do to the vector via VecShift we will also do
 39:   // to the copy, and hence they should always match
 40:   PetscCall(VecGetLocalSize(x, &n));
 41:   PetscCall(PetscMalloc1(n, &array_copy));
 42:   PetscCall(VecGetArrayRead(x, &array));
 43:   PetscCall(PetscArraycpy(array_copy, array, n));
 44:   PetscCall(VecRestoreArrayRead(x, &array));

 46:   PetscCall(CheckVecShift(x, n, array_copy, 0.0));
 47:   PetscCall(CheckVecShift(x, n, array_copy, 1.0));
 48:   PetscCall(CheckVecShift(x, n, array_copy, -1.0));
 49:   PetscCall(CheckVecShift(x, n, array_copy, 15.0));

 51:   PetscCall(VecNorm(x, NORM_2, &norm_before));
 52:   PetscCall(VecNormAvailable(x, NORM_2, &available, &norm_after));
 53:   PetscCheck(available, PETSC_COMM_SELF, PETSC_ERR_PLIB, "VecNormAvailable() returned FALSE right after calling VecNorm()");
 54:   // a shift of zero should not invalidate norms
 55:   PetscCall(CheckVecShift(x, n, array_copy, 0.0));
 56:   PetscCall(VecNormAvailable(x, NORM_2, &available, &norm_after));
 57:   PetscCheck(available, PETSC_COMM_SELF, PETSC_ERR_PLIB, "VecNormAvailable() returned FALSE after calling VecShift() with a shift of 0.0!");
 58:   // these can be compared with equality as the number should not change *at all*
 59:   PetscCheck(norm_before == norm_after, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Norms differ before and after calling VecShift() with shift of 0.0: before %g after %g", (double)norm_before, (double)norm_after);

 61:   PetscCall(PetscFree(array_copy));
 62:   PetscCall(VecDestroy(&x));
 63:   PetscCall(PetscFinalize());
 64:   return 0;
 65: }

 67: /*TEST

 69:   testset:
 70:     output_file: output/empty.out
 71:     nsize: {{1 2}}
 72:     test:
 73:       suffix: standard
 74:     test:
 75:       requires: defined(PETSC_USE_SHARED_MEMORY)
 76:       args: -vec_type shared
 77:       suffix: shared
 78:     test:
 79:       requires: viennacl
 80:       args: -vec_type viennacl
 81:       suffix: viennacl
 82:     test:
 83:       requires: kokkos_kernels
 84:       args: -vec_type kokkos
 85:       suffix: kokkos
 86:     test:
 87:       requires: cuda
 88:       args: -vec_type cuda
 89:       suffix: cuda
 90:     test:
 91:       requires: hip
 92:       args: -vec_type hip
 93:       suffix: hip

 95: TEST*/