bool
  CGPerturbationHandler::PerturbForWrongInertia(
    Number& delta_x, Number& delta_s,
    Number& delta_c, Number& delta_d)
  {
    DBG_START_METH("CGPerturbationHandler::PerturbForWrongInertia",
                   dbg_verbosity);

    // Check if we can conclude that components of the system are
    // structurally degenerate (we only get here if the most recent
    // perturbation for a test did not result in a singular system)
    finalize_test();

    bool retval = get_deltas_for_wrong_inertia(delta_x, delta_s, delta_c, delta_d);
    if (!retval && delta_c==0.) {
      DBG_ASSERT(delta_d == 0.);
      delta_c_curr_ = delta_cd();
      delta_d_curr_ = delta_c_curr_;
      delta_x_curr_ = 0.;
      delta_s_curr_ = 0.;
      test_status_ = NO_TEST;
      if (hess_degenerate_ == DEGENERATE) {
        hess_degenerate_ = NOT_YET_DETERMINED;
      }
      retval = get_deltas_for_wrong_inertia(delta_x, delta_s, delta_c, delta_d);
    }
    return retval;
  }
int SimpleExample(int argc, char * argv[])
{
    float angle;

    /* To remove warning */
    (void)argc;
    (void)argv;

  /* Normally, the first thing that you do is set up your communication and
   * then create at least one ICE-T context.  This has already been done in
   * the calling function (i.e. icetTests_mpi.c).  See the init_mpi_comm in
   * mpi_comm.h for an example.
   */

  /* If we had set up the communication layer ourselves, we could have
   * gotten these parameters directly from it.  Since we did not, this
   * provides an alternate way. */
    icetGetIntegerv(ICET_RANK, &rank);
    icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc);

  /* We should be able to set any color we want, but we should do it BEFORE
   * icetDrawFrame() is called, not in the callback drawing function.
   * There may also be limitations on the background color when performing
   * color blending. */
    glClearColor(0.2f, 0.5f, 0.1f, 1.0f);

  /* Give ICE-T a function that will issue the OpenGL drawing commands. */
    icetDrawFunc(draw);

  /* Give ICE-T the bounds of the polygons that will be drawn.  Note that
   * we must take into account any transformation that happens within the
   * draw function (but ICE-T will take care of any transformation that
   * happens before icetDrawFrame). */
    icetBoundingBoxf(-0.5f+rank, 0.5f+rank, -0.5, 0.5, -0.5, 0.5);

  /* Set up the tiled display.  Normally, the display will be fixed for a
   * given installation, but since this is a demo, we give two specific
   * examples. */
    if (num_proc < 4) {
      /* Here is an example of a "1 tile" case.  This is functionally
       * identical to a traditional sort last algorithm. */
        icetResetTiles();
        icetAddTile(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0);
    } else {
      /* Here is an example of a 4x4 tile layout.  The tiles are displayed
       * with the following ranks:
       *
       *               +---+---+
       *               | 0 | 1 |
       *               +---+---+
       *               | 2 | 3 |
       *               +---+---+
       *
       * Each tile is simply defined by grabing a viewport in an infinite
       * global display screen.  The global viewport projection is
       * automatically set to the smallest region containing all tiles.
       *
       * This example also shows tiles abutted against each other.
       * Mullions and overlaps can be implemented by simply shifting tiles
       * on top of or away from each other.
       */
        icetResetTiles();
        icetAddTile(0,           SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, 0);
        icetAddTile(SCREEN_WIDTH,SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, 1);
        icetAddTile(0,           0,             SCREEN_WIDTH, SCREEN_HEIGHT, 2);
        icetAddTile(SCREEN_WIDTH,0,             SCREEN_WIDTH, SCREEN_HEIGHT, 3);
    }

  /* Tell ICE-T what strategy to use.  The REDUCE strategy is an all-around
   * good performer. */
    icetStrategy(ICET_STRATEGY_REDUCE);

  /* Set up the projection matrix as you normally would. */
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-0.75, 0.75, -0.75, 0.75, -0.75, 0.75);

  /* Other normal OpenGL setup. */
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    if (rank%8 != 0) {
        GLfloat color[4];
        color[0] = (float)(rank%2);
        color[1] = (float)((rank/2)%2);
        color[2] = (float)((rank/4)%2);
        color[3] = 1.0;
        glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
    }

  /* Here is an example of an animation loop. */
    for (angle = 0; angle < 360; angle += 10) {
      /* We can set up a modelview matrix here and ICE-T will factor this
       * in determining the screen projection of the geometry.  Note that
       * there is further transformation in the draw function that ICE-T
       * cannot take into account.  That transformation is handled in the
       * application by deforming the bounds before giving them to
       * ICE-T. */
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glRotatef(angle, 0.0, 1.0, 0.0);
        glScalef(1.0f/num_proc, 1.0, 1.0);
        glTranslatef(-(num_proc-1)/2.0f, 0.0, 0.0);

      /* Instead of calling draw() directly, call it indirectly through
       * icetDrawFrame().  ICE-T will automatically handle image
       * compositing. */
        icetDrawFrame();

      /* For obvious reasons, ICE-T should be run in double-buffered frame
       * mode.  After calling icetDrawFrame, the application should do a
       * synchronize (a barrier is often about as good as you can do) and
       * then a swap buffers. */
        swap_buffers();
    }

    finalize_test(TEST_PASSED);
    return TEST_PASSED;
}
int BlankTiles(int argc, char *argv[])
{
    int i, j, x, y;
    GLubyte *cb;
    int result = TEST_PASSED;
    GLint rank, num_proc;

    /* To remove warning */
    (void)argc;
    (void)argv;

    icetGetIntegerv(ICET_RANK, &rank);
    icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc);

    glClearColor(0.0, 0.0, 0.0, 0.0);

    icetDrawFunc(draw);
    icetBoundingBoxf(-0.5, 0.5, -0.5, 0.5, -0.5, 0.5);

    for (i = 0; i < STRATEGY_LIST_SIZE; i++) {
        int tile_dim;

        icetStrategy(strategy_list[i]);
        printf("\n\nUsing %s strategy.\n", icetGetStrategyName());

        for (tile_dim = 1; tile_dim*tile_dim <= num_proc; tile_dim++) {
            printf("\nRunning on a %d x %d display.\n", tile_dim, tile_dim);
            icetResetTiles();
            for (y = 0; y < tile_dim; y++) {
                for (x = 0; x < tile_dim; x++) {
                    icetAddTile(x*SCREEN_WIDTH, y*SCREEN_HEIGHT,
                                SCREEN_WIDTH, SCREEN_HEIGHT, y*tile_dim + x);
                }
            }

            printf("Rendering frame.\n");
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            glOrtho(-1, tile_dim*2-1, -1, tile_dim*2-1, -1, 1);
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
            icetDrawFrame();
            swap_buffers();

            if (rank == 0) {
                printf("Rank == 0, tile should have stuff in it.\n");
            } else if (rank < tile_dim*tile_dim) {
                printf("Checking returned image.\n");
                cb = icetGetColorBuffer();
                for (j = 0; j < SCREEN_WIDTH*SCREEN_HEIGHT*4; j++) {
                    if (cb[j] != 0) {
                        printf("Found bad pixel!!!!!!!!\n");
                        result = TEST_FAILED;
                        break;
                    }
                }
            } else {
                printf("Not a display node.  Not testing image.\n");
            }
        }
    }

    printf("Cleaning up.\n");

    finalize_test(result);
    return result;
}
int DisplayNoDraw(int argc, char *argv[])
{
    int result = TEST_PASSED;
    int i;
    GLint rank, num_proc;

    /* To remove warning */
    (void)argc;
    (void)argv;

    icetGetIntegerv(ICET_RANK, &rank);
    icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc);

    printf("Starting DisplayNoDraw.\n");

    global_rank = rank;

    printf("Setting tile.");
    icetResetTiles();
    icetAddTile(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0);

    icetDrawFunc(draw);

    if (rank == 0) {
        icetBoundingBoxf(100.0, 101.0, 100.0, 101.0, 100.0, 101.0);
    } else {
        icetBoundingBoxf(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
    }

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-0.5, 0.5, -0.5, 0.5, -0.5, 0.5);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glDisable(GL_LIGHTING);
    glColor4f(1.0, 1.0, 1.0, 1.0);

    for (i = 0; i < STRATEGY_LIST_SIZE; i++) {
        GLubyte *color_buffer;

        icetStrategy(strategy_list[i]);
        printf("\n\nUsing %s strategy.\n", icetGetStrategyName());

        for (iteration = 0; iteration < num_proc; iteration++) {
            printf("Blank tile is rank %d\n", iteration);

            icetDrawFrame();
            swap_buffers();

            if (   (rank == 0)
                && (num_proc > 1)
               /* This last case covers when there is only 2 processes,
                * the root, as always, is not drawing anything and the
                * other process is drawing the clear screen. */
                && ((num_proc > 2) || (iteration != 1)) ) {
                int p;
                int bad_count = 0;
                printf("Checking pixels.\n");
                color_buffer = icetGetColorBuffer();
                for (p = 0; p < SCREEN_WIDTH*SCREEN_HEIGHT*4; p++) {
                    if (color_buffer[p] != 255) {
                        char filename[256];
                        printf("BAD PIXEL %d.%d\n", p/4, p%4);
                        printf("    Expected 255, got %d\n", color_buffer[p]);
                        bad_count++;
                        if (bad_count >= 10) {
                            result = TEST_FAILED;
                            sprintf(filename, "DisplayNoDraw_%s_%d.ppm",
                                    icetGetStrategyName(), iteration);
                            write_ppm(filename, color_buffer,
                                      SCREEN_WIDTH, SCREEN_HEIGHT);
                            break;
                        }
                    }
                }
            }
        }
    }

    finalize_test(result);
    return result;
}
  bool
  CGPerturbationHandler::ConsiderNewSystem(Number& delta_x, Number& delta_s,
      Number& delta_c, Number& delta_d)
  {
    DBG_START_METH("CGPerturbationHandler::ConsiderNewSystem",dbg_verbosity);

    // Check if we can conclude that some components of the system are
    // structurally degenerate
    finalize_test();
    // If the current iterate is restored from a previous iteration,
    // initialize perturbationhandler data
    if (CGPenData().restor_iter() == IpData().iter_count()) {
      hess_degenerate_ = NOT_YET_DETERMINED;
      jac_degenerate_ = NOT_YET_DETERMINED;
      degen_iters_ = 0;
      hess_degenerate_ = NOT_DEGENERATE;
      jac_degenerate_ = NOT_DEGENERATE;
      delta_x_curr_ = 0.;
      delta_s_curr_ = 0.;
      delta_c_curr_ = 0.;
      delta_d_curr_ = 0.;
      delta_x_last_ = 0.;
      delta_s_last_ = 0.;
      delta_c_last_ = 0.;
      delta_d_last_ = 0.;
      test_status_ = NO_TEST;
    }

    // Store the perturbation from the previous matrix
    if (reset_last_) {
      delta_x_last_ = delta_x_curr_;
      delta_s_last_ = delta_s_curr_;
      delta_c_last_ = delta_c_curr_;
      delta_d_last_ = delta_d_curr_;
    }
    else {
      if (delta_x_curr_ > 0.) {
        delta_x_last_ = delta_x_curr_;
      }
      if (delta_s_curr_ > 0.) {
        delta_s_last_ = delta_s_curr_;
      }
      if (delta_c_curr_ > 0.) {
        delta_c_last_ = delta_c_curr_;
      }
      if (delta_d_curr_ > 0.) {
        delta_d_last_ = delta_d_curr_;
      }
    }

    DBG_ASSERT((hess_degenerate_ != NOT_YET_DETERMINED ||
                jac_degenerate_ != DEGENERATE) &&
               (jac_degenerate_ != NOT_YET_DETERMINED ||
                hess_degenerate_ != DEGENERATE));

    if (hess_degenerate_ == NOT_YET_DETERMINED ||
        jac_degenerate_ == NOT_YET_DETERMINED) {
      if (!perturb_always_cd_
          || CGPenCq().curr_cg_pert_fact() < delta_cd()
          || !CGPenData().NeverTryPureNewton()) {
        test_status_ = TEST_DELTA_C_EQ_0_DELTA_X_EQ_0;
      }
      else {
        test_status_ = TEST_DELTA_C_GT_0_DELTA_X_EQ_0;
      }
    }
    else {
      test_status_ = NO_TEST;
    }

    Number pert_fact = CGPenCq().curr_cg_pert_fact();
    if (jac_degenerate_ == DEGENERATE
        || CGPenData().NeverTryPureNewton()
        || perturb_always_cd_) {
      Number mach_eps = std::numeric_limits<Number>::epsilon();
      if (pert_fact < 100.*mach_eps
          && jac_degenerate_ == DEGENERATE) {
        delta_c = delta_c_curr_ = 100.*mach_eps;
      }
      else {
        delta_c = delta_c_curr_ = pert_fact;
      }
    }
    else {
      delta_c = delta_c_curr_ = 0.;
    }
    CGPenData().SetCurrPenaltyPert(delta_c);

    delta_d = delta_d_curr_ = delta_c;

    if (hess_degenerate_ == DEGENERATE) {
      delta_x_curr_ = 0.;
      delta_s_curr_ = 0.;
      bool retval = get_deltas_for_wrong_inertia(delta_x, delta_s,
                    delta_c, delta_d);
      if (!retval) {
        return false;
      }
    }
    else {
      delta_x = 0.;
      delta_s = delta_x;
    }

    delta_x_curr_ = delta_x;
    delta_s_curr_ = delta_s;
    delta_c_curr_ = delta_c;
    delta_d_curr_ = delta_d;

    IpData().Set_info_regu_x(delta_x);

    get_deltas_for_wrong_inertia_called_ = false;

    return true;
  }
int BoundsBehindViewer(int argc, char * argv[])
{
    float mat[16];

    /* To remove warning */
    (void)argc;
    (void)argv;

    GLint rank;
    icetGetIntegerv(ICET_RANK, &rank);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    icetDrawFunc(draw);
    icetStrategy(ICET_STRATEGY_REDUCE);

    icetBoundingBoxf(-1.0, 1.0, -1.0, 1.0, -0.0, 0.0);

  /* We're just going to use one tile. */
    icetResetTiles();
    icetAddTile(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0);

  /* Set up the transformation such that the quad in draw should cover the
     entire screen, but part of it extends behind the viewpoint.  Furthermore, a
     naive division by w will show all points to the right of the screen (which,
     of course, is wrong). */
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -1.5);
    glRotatef(10.0, 0.0, 1.0, 0.0);
    glScalef(10.0, 10.0, 10.0);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 2.0);

    printf("Modelview matrix:\n");
    glGetFloatv(GL_MODELVIEW_MATRIX, mat);
    PrintMatrix(mat);
    printf("Projection matrix:\n");
    glGetFloatv(GL_PROJECTION_MATRIX, mat);
    PrintMatrix(mat);

  /* Other normal OpenGL setup. */
    glEnable(GL_DEPTH_TEST);
    glDisable(GL_LIGHTING);
    glColor3f(1.0, 1.0, 1.0);

  /* All the processes have the same data.  Go ahead and tell IceT. */
    icetDataReplicationGroupColor(0);

    icetDrawFrame();

  /* Test the resulting image to make sure the polygon was drawn over it. */
    if (rank == 0) {
        GLuint *cb = (GLuint *)icetGetColorBuffer();
        if (cb[0] != 0xFFFFFFFF) {
            printf("First pixel in color buffer wrong: 0x%x\n", cb[0]);
            finalize_test(TEST_FAILED);
            return TEST_FAILED;
        }
    }

    finalize_test(TEST_PASSED);
    return TEST_PASSED;
}
  bool
  PDPerturbationHandler::ConsiderNewSystem(Number& delta_x, Number& delta_s,
      Number& delta_c, Number& delta_d)
  {
    DBG_START_METH("PDPerturbationHandler::ConsiderNewSystem",dbg_verbosity);

    // Check if we can conclude that some components of the system are
    // structurally degenerate
    finalize_test();

    // Store the perturbation from the previous matrix
    if (reset_last_) {
      delta_x_last_ = delta_x_curr_;
      delta_s_last_ = delta_s_curr_;
      delta_c_last_ = delta_c_curr_;
      delta_d_last_ = delta_d_curr_;
    }
    else {
      if (delta_x_curr_ > 0.) {
        delta_x_last_ = delta_x_curr_;
      }
      if (delta_s_curr_ > 0.) {
        delta_s_last_ = delta_s_curr_;
      }
      if (delta_c_curr_ > 0.) {
        delta_c_last_ = delta_c_curr_;
      }
      if (delta_d_curr_ > 0.) {
        delta_d_last_ = delta_d_curr_;
      }
    }

    DBG_ASSERT((hess_degenerate_ != NOT_YET_DETERMINED ||
                jac_degenerate_ != DEGENERATE) &&
               (jac_degenerate_ != NOT_YET_DETERMINED ||
                hess_degenerate_ != DEGENERATE));

    if (hess_degenerate_ == NOT_YET_DETERMINED ||
        jac_degenerate_ == NOT_YET_DETERMINED) {
      test_status_ = TEST_DELTA_C_EQ_0_DELTA_X_EQ_0;
    }
    else {
      test_status_ = NO_TEST;
    }

    if (jac_degenerate_ == DEGENERATE) {
      delta_c = delta_c_curr_ = delta_cd();
      IpData().Append_info_string("l");
    }
    else {
      delta_c = delta_c_curr_ = 0.;
    }
    delta_d = delta_d_curr_ = delta_c;

    if (hess_degenerate_ == DEGENERATE) {
      delta_x_curr_ = 0.;
      delta_s_curr_ = 0.;
      bool retval = get_deltas_for_wrong_inertia(delta_x, delta_s,
                    delta_c, delta_d);
      if (!retval) {
        return false;
      }
    }
    else {
      delta_x = 0.;
      delta_s = delta_x;
    }

    delta_x_curr_ = delta_x;
    delta_s_curr_ = delta_s;
    delta_c_curr_ = delta_c;
    delta_d_curr_ = delta_d;

    IpData().Set_info_regu_x(delta_x);

    get_deltas_for_wrong_inertia_called_ = false;

    return true;
  }