/* nag_mesh2d_delaunay (d06abc) 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)
{
  const Integer nvmax = 6000, nvint = 40;
  double        dnvint;
  Integer       exit_status, i, itrace, j, k, nedge, nelt,
                npropa, nv, nvb, reftk, i1;
  NagError      fail;
  char          pmesh[2];
  double        *coor = 0, *weight = 0;
  Integer       *conn = 0, *edge = 0;

  INIT_FAIL(fail);

  exit_status = 0;

  printf("nag_mesh2d_delaunay (d06abc) Example Program Results\n\n");

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

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

  if (nvb > nvmax)
    {
      printf("Problem with the array dimensions\n");
      printf(" nvb nvmax %6ld%6ld\n", nvb, nvmax);
      printf(" Please increase the value of nvmax\n");
      exit_status = -1;
      goto END;
    }

  /* Allocate memory */

  if (!(coor = NAG_ALLOC(2*nvmax, double)) ||
      !(weight = NAG_ALLOC(nvint, double)) ||
      !(conn = NAG_ALLOC(3*(2*nvmax + 5), Integer)) ||
      !(edge = NAG_ALLOC(3*nedge, Integer)))
    {
      printf("Allocation failure\n");
      exit_status = -1;
      goto END;
    }

  /* Coordinates of the boundary mesh vertices and boundary edges */

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

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

  /* Initialise mesh control parameters */

  itrace = 0;

  /* Generation of interior vertices on the RAE airfoils wake */

  dnvint = 2.5/(double)(nvint + 1);

  for (i = 1; i <= nvint; ++i)
    {
      i1 = nvb + i;
      COOR(1, i1) = (double) i*dnvint + 1.38;
      COOR(2, i1) = -0.27*COOR(1, i1) + 0.2;
      weight[i-1] = 0.01;
    }

  /* Loop on the propagation coef */

  for (j = 0; j < 4; ++j)
    {
      switch (j)
        {
        case 0:
          npropa = -5;
          break;
        case 1:
          npropa = -1;
          break;
        case 2:
          npropa = 1;
          break;
        default:
          npropa = 5;
        }

      /* Call to the 2D Delaunay-Voronoi mesh generator */

      /* nag_mesh2d_delaunay (d06abc).
       * Generates a two-dimensional mesh using a Delaunay-Voronoi
       * process
       */
      nag_mesh2d_delaunay(nvb, nvint, nvmax, nedge, edge, &nv, &nelt, coor,
                          conn, weight, npropa, itrace, 0, &fail);

      if (fail.code == NE_NOERROR)
        {
          if (pmesh[0] == 'N')
            {
              printf(" Mesh characteristics with npropa =%6ld\n",
                      npropa);
              printf(" nv   =%6ld\n", nv);
              printf(" nelt =%6ld\n", nelt);
            }
          else if (pmesh[0] == 'Y')
            {
              /* Output the 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 (k = 1; k <= nelt; ++k)
                {
                  printf(" %10ld %10ld %10ld"
                         " %10ld\n", CONN(1, k), CONN(2, k),
                         CONN(3, k), reftk);
                }
            }
          else
            {
              printf("Problem with the printing option Y or N\n");
              exit_status = -1;
              goto END;
            }
        }
      else
        {
          printf("Error from nag_mesh2d_delaunay (d06abc).\n%s\n",
                  fail.message);
          exit_status = 1;
          goto END;
        }
    }

 END:
  NAG_FREE(coor);
  NAG_FREE(weight);
  NAG_FREE(conn);
  NAG_FREE(edge);

  return exit_status;
}