Actual source code: taoboundtest.c

  1: static char help[] = "Tests TAO utilities with one-sided variable bounds.\n";

  3: #include <petsctao.h>

  5: static PetscErrorCode SetSolution(Vec x)
  6: {
  7:   PetscScalar *values;
  8:   PetscInt     i, rstart, rend;

 10:   PetscFunctionBeginUser;
 11:   PetscCall(VecGetOwnershipRange(x, &rstart, &rend));
 12:   PetscCall(VecGetArray(x, &values));
 13:   for (i = rstart; i < rend; ++i) values[i - rstart] = i == 0 ? -2.0 : (i == 3 ? 2.0 : 0.0);
 14:   PetscCall(VecRestoreArray(x, &values));
 15:   PetscFunctionReturn(PETSC_SUCCESS);
 16: }

 18: static PetscErrorCode CheckSolution(Vec x, PetscBool lower)
 19: {
 20:   const PetscScalar *values;
 21:   PetscInt           i, rstart, rend;

 23:   PetscFunctionBeginUser;
 24:   PetscCall(VecGetOwnershipRange(x, &rstart, &rend));
 25:   PetscCall(VecGetArrayRead(x, &values));
 26:   for (i = rstart; i < rend; ++i) {
 27:     PetscScalar expected = i == 0 ? (lower ? -1.0 : -2.0) : (i == 3 ? (lower ? 2.0 : 1.0) : 0.0);

 29:     PetscCheck(values[i - rstart] == expected, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected value at index %" PetscInt_FMT, i);
 30:   }
 31:   PetscCall(VecRestoreArrayRead(x, &values));
 32:   PetscFunctionReturn(PETSC_SUCCESS);
 33: }

 35: static PetscErrorCode TestActiveBounds(Vec x, Vec bound, Vec g, Vec s, Vec work, PetscBool lower)
 36: {
 37:   IS        active_lower = NULL, active_upper = NULL, active_fixed = NULL, active = NULL, inactive = NULL;
 38:   IS        active_bound;
 39:   PetscReal bound_tol = 0.0;
 40:   PetscInt  n;

 42:   PetscFunctionBeginUser;
 43:   PetscCall(SetSolution(x));
 44:   PetscCall(VecSet(g, lower ? 1.0 : -1.0));
 45:   PetscCall(VecSet(s, 0.0));
 46:   PetscCall(TaoEstimateActiveBounds(x, lower ? bound : NULL, lower ? NULL : bound, g, s, work, 1.0, &bound_tol, &active_lower, &active_upper, &active_fixed, &active, &inactive));
 47:   active_bound = lower ? active_lower : active_upper;
 48:   PetscCheck(active_bound, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Expected an active bound");
 49:   PetscCall(ISGetSize(active_bound, &n));
 50:   PetscCheck(n == 1, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Expected one active bound, got %" PetscInt_FMT, n);
 51:   PetscCheck(!(lower ? active_upper : active_lower), PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Unexpected active bound on the unbounded side");
 52:   PetscCall(ISDestroy(&active_lower));
 53:   PetscCall(ISDestroy(&active_upper));
 54:   PetscCall(ISDestroy(&active_fixed));
 55:   PetscCall(ISDestroy(&active));
 56:   PetscCall(ISDestroy(&inactive));
 57:   PetscFunctionReturn(PETSC_SUCCESS);
 58: }

 60: int main(int argc, char **argv)
 61: {
 62:   Vec      x, xl, xu, g, s, work;
 63:   PetscInt nDiff;

 65:   PetscFunctionBeginUser;
 66:   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
 67:   PetscCall(VecCreate(PETSC_COMM_WORLD, &x));
 68:   PetscCall(VecSetSizes(x, PETSC_DECIDE, 4));
 69:   PetscCall(VecSetFromOptions(x));
 70:   PetscCall(VecDuplicate(x, &xl));
 71:   PetscCall(VecDuplicate(x, &xu));
 72:   PetscCall(VecDuplicate(x, &g));
 73:   PetscCall(VecDuplicate(x, &s));
 74:   PetscCall(VecDuplicate(x, &work));
 75:   PetscCall(VecSet(xl, -1.0));
 76:   PetscCall(VecSet(xu, 1.0));

 78:   PetscCall(SetSolution(x));
 79:   PetscCall(TaoBoundSolution(x, xl, NULL, 0.0, &nDiff, x));
 80:   PetscCheck(nDiff == 1, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Expected one lower-bound correction, got %" PetscInt_FMT, nDiff);
 81:   PetscCall(CheckSolution(x, PETSC_TRUE));

 83:   PetscCall(SetSolution(x));
 84:   PetscCall(TaoBoundSolution(x, NULL, xu, 0.0, &nDiff, x));
 85:   PetscCheck(nDiff == 1, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Expected one upper-bound correction, got %" PetscInt_FMT, nDiff);
 86:   PetscCall(CheckSolution(x, PETSC_FALSE));

 88:   PetscCall(TestActiveBounds(x, xl, g, s, work, PETSC_TRUE));
 89:   PetscCall(TestActiveBounds(x, xu, g, s, work, PETSC_FALSE));

 91:   PetscCall(VecDestroy(&x));
 92:   PetscCall(VecDestroy(&xl));
 93:   PetscCall(VecDestroy(&xu));
 94:   PetscCall(VecDestroy(&g));
 95:   PetscCall(VecDestroy(&s));
 96:   PetscCall(VecDestroy(&work));
 97:   PetscCall(PetscFinalize());
 98:   return 0;
 99: }

101: /*TEST

103:   build:
104:     requires: !complex

106:   test:
107:     output_file: output/empty.out

109:   test:
110:     suffix: 2
111:     nsize: 2
112:     output_file: output/empty.out

114: TEST*/