/* nag_mesh2d_renum (d06ccc) Example Program.
 *
 * Copyright 2014 Numerical Algorithms Group.
 *
 * Mark 7, 2001.
 */

#include <stdio.h>
#include <nag.h>
#include <nag_stdlib.h>
#include <nagd06.h>

#define EDGE(I, J) edge[3*((J) -1)+(I) -1]
#define CONN(I, J) conn[3*((J) -1)+(I) -1]
#define COOR(I, J) coor[2*((J) -1)+(I) -1]

int main(void)
{
  Integer  exit_status, i, itrace, nedge, nelt, nnz, nnzmax, nv, reftk;
  NagError fail;
  char     pmesh[2];
  double   *coor = 0;
  Integer  *conn = 0, *edge = 0, *icol = 0, *irow = 0;

  INIT_FAIL(fail);

  exit_status = 0;

  printf(" nag_mesh2d_renum (d06ccc) Example Program Results\n\n");
  fflush(stdout);

  /* Skip heading in data file */
  scanf("%*[^\n] ");

  /* Reading of the geometry */
  scanf("%ld", &nv);
  scanf("%ld", &nelt);
  scanf("%ld", &nedge);
  scanf("%*[^\n] ");

  nnzmax = 10*nv;

  /* Allocate memory */

  if (!(coor = NAG_ALLOC(2*nv, double)) ||
      !(conn = NAG_ALLOC(3*nelt, Integer)) ||
      !(edge = NAG_ALLOC(3*nedge, Integer)) ||
      !(irow = NAG_ALLOC(nnzmax, Integer)) ||
      !(icol = NAG_ALLOC(nnzmax, Integer)))
    {
      printf("Allocation failure\n");
      exit_status = -1;
      goto END;
    }

  for (i = 1; i <= nv; ++i)
    {
      scanf("%lf", &COOR(1, i));
      scanf("%lf", &COOR(2, i));
      scanf("%*[^\n] ");
    }

  for (i = 1; i <= nelt; ++i)
    {
      scanf("%ld", &CONN(1, i));
      scanf("%ld", &CONN(2, i));
      scanf("%ld", &CONN(3, i));
      scanf("%ld", &reftk);
      scanf("%*[^\n] ");
    }

  for (i = 1; i <= nedge; ++i)
    {
      scanf("%ld", &reftk);
      scanf("%ld", &EDGE(1, i));
      scanf("%ld", &EDGE(2, i));
      scanf("%ld", &EDGE(3, i));
      scanf("%*[^\n] ");
    }
  scanf(" ' %1s '", pmesh);
  scanf("%*[^\n] ");

  /* Compute the sparsity of the FE matrix */
  /* from the input geometry */

  /* nag_mesh2d_sparse (d06cbc).
   * Generates a sparsity pattern of a Finite Element matrix
   * associated with a given mesh
   */
  nag_mesh2d_sparse(nv, nelt, nnzmax, conn, &nnz, irow, icol, &fail);

  if (fail.code == NE_NOERROR)
    {
      if (pmesh[0] == 'N')
        {
          printf(" The Matrix Sparsity characteristics\n");
          printf(" before the renumbering\n");
          printf(" nv  =%6ld\n", nv);
          printf(" nnz =%6ld\n", nnz);
        }
      else if (pmesh[0] == 'Y')
        {
          /* Output the sparsity of the mesh to view */
          /* it using the NAG Graphics Library */

          printf(" %10ld%10ld\n", nv, nnz);

          for (i = 0; i < nnz; ++i)
            printf(" %10ld%10ld\n", irow[i], icol[i]);
        }
      else
        {
          printf("Problem with the printing option Y or N\n");
          exit_status = -1;
          goto END;
        }
    }
  else
    {
      printf("Error from nag_mesh2d_sparse (d06cbc).\n%s\n",
              fail.message);
      exit_status = 1;
      goto END;
    }

  /* Call the renumbering routine and get the new sparsity */

  itrace = 1;

  /* nag_mesh2d_renum (d06ccc).
   * Renumbers a given mesh using Gibbs method
   */
  fflush(stdout);
  nag_mesh2d_renum(nv, nelt, nedge, nnzmax, &nnz, coor, edge, conn, irow, icol,
                   itrace, 0, &fail);
  if (fail.code == NE_NOERROR)
    {
      if (pmesh[0] == 'N')
        {
          printf("\n The Matrix Sparsity characteristics\n");
          printf(" after the renumbering\n");
          printf(" nv   =%6ld\n", nv);
          printf(" nnz  =%6ld\n", nnz);
          printf(" nelt =%6ld\n", nelt);
        }
      else if (pmesh[0] == 'Y')
        {
          /* Output the sparsity of the renumbered mesh */
          /* to view it using the NAG Graphics Library */

          printf("%10ld%10ld\n", nv, nnz);

          for (i = 0; i < nnz; ++i)
            printf(" %10ld%10ld\n", irow[i], icol[i]);

          /* Output the renumbered mesh to view */
          /* it using the NAG Graphics Library */

          printf(" %10ld%10ld\n", nv, nelt);

          for (i = 1; i <= nv; ++i)
            printf("  %15.6e  %15.6e  \n",
                    COOR(1, i), COOR(2, i));

          reftk = 0;
          for (i = 1; i <= nelt; ++i)
            printf(" %10ld%10ld%10ld%10ld\n",
                    CONN(1, i), CONN(2, i), CONN(3, i), reftk);
        }
    }
  else
    {
      printf("Error from nag_mesh2d_renum (d06ccc).\n%s\n",
              fail.message);
      exit_status = 1;
      goto END;
    }

 END:
  NAG_FREE(coor);
  NAG_FREE(conn);
  NAG_FREE(edge);
  NAG_FREE(irow);
  NAG_FREE(icol);

  return exit_status;
}