```/* nag_mesh2d_join (d06dbc) Example Program.
*
* Copyright 2017 Numerical Algorithms Group.
*
* Mark 26.1, 2017.
*/

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

#ifdef __cplusplus
extern "C"
{
#endif
static double NAG_CALL fbnd(Integer, double, double, Nag_Comm *);
#ifdef __cplusplus
}
#endif

static int ex1(void);
static int ex2(void);

#define EDGE1(I, J)  edge1[3*((J) -1)+(I) -1]
#define EDGE2(I, J)  edge2[3*((J) -1)+(I) -1]
#define EDGE3(I, J)  edge3[3*((J) -1)+(I) -1]
#define EDGE5(I, J)  edge5[3*((J) -1)+(I) -1]
#define CONN1(I, J)  conn1[3*((J) -1)+(I) -1]
#define CONN3(I, J)  conn3[3*((J) -1)+(I) -1]
#define CONN5(I, J)  conn5[3*((J) -1)+(I) -1]
#define COOR1(I, J)  coor1[2*((J) -1)+(I) -1]
#define COOR3(I, J)  coor3[2*((J) -1)+(I) -1]
#define COOR5(I, J)  coor5[2*((J) -1)+(I) -1]
#define TRANS(I, J)  trans[6*((J) -1)+(I) -1]
#define LINED(I, J)  lined[4*((J) -1)+(I) -1]
#define COORCH(I, J) coorch[2*(J-1)+I-1]

int main(void)
{
Integer exit_status_ex1 = 0;
Integer exit_status_ex2 = 0;

printf("nag_mesh2d_join (d06dbc) Example Program Results\n");
exit_status_ex1 = ex1();
exit_status_ex2 = ex2();

return (exit_status_ex1 == 0 && exit_status_ex2 == 0) ? 0 : 1;
}

int ex1(void)
{
const Integer nvmax = 900, nedmx = 200, neltmx = 2 * nvmax + 5, ntrans = 1,
mode = 0;
double eps;
Integer exit_status, i, imax, itrace, itrans, jmax, jtrans, k, ktrans;
Integer nedge1, nedge2, nedge3, nelt1, nelt2, nelt3, nv1, nv2, nv3, reftk;
Integer imaxm1, jmaxm1, ind;
char pmesh[2];
double *coor1 = 0, *coor2 = 0, *coor3 = 0, *trans = 0;
Integer *conn1 = 0, *conn2 = 0, *conn3 = 0, *edge1 = 0, *edge2 = 0;
Integer *edge3 = 0, *itype = 0, *reft1 = 0, *reft2 = 0, *reft3 = 0;
NagError fail;

INIT_FAIL(fail);
exit_status = 0;

printf("\nExample 1\n\n");

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

/* Read the mesh: coordinates and connectivity of the 1st domain */
scanf("%" NAG_IFMT "", &nv1);
scanf("%" NAG_IFMT "", &nelt1);
scanf("%*[^\n] ");

nv2 = nv1;
nelt2 = nelt1;

imax = 20;
jmax = imax;
imaxm1 = imax - 1;
jmaxm1 = jmax - 1;
nedge1 = 2 * (imaxm1 + jmaxm1);
nedge2 = nedge1;

/* Allocate memory */

if (!(coor1 = NAG_ALLOC(2 * nv1, double)) ||
!(coor2 = NAG_ALLOC(2 * nv2, double)) ||
!(coor3 = NAG_ALLOC(2 * nvmax, double)) ||
!(trans = NAG_ALLOC(6 * ntrans, double)) ||
!(conn1 = NAG_ALLOC(3 * nelt1, Integer)) ||
!(conn2 = NAG_ALLOC(3 * nelt2, Integer)) ||
!(conn3 = NAG_ALLOC(3 * neltmx, Integer)) ||
!(edge1 = NAG_ALLOC(3 * nedge1, Integer)) ||
!(edge2 = NAG_ALLOC(3 * nedge2, Integer)) ||
!(edge3 = NAG_ALLOC(3 * nedmx, Integer)) ||
!(itype = NAG_ALLOC(ntrans, Integer)) ||
!(reft1 = NAG_ALLOC(nelt1, Integer)) ||
!(reft2 = NAG_ALLOC(nelt2, Integer)) ||
!(reft3 = NAG_ALLOC(neltmx, Integer)))
{
printf("Allocation failure\n");
exit_status = -1;
goto END;
}

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

for (k = 1; k <= nelt1; ++k) {
scanf("%" NAG_IFMT "", &CONN1(1, k));
scanf("%" NAG_IFMT "", &CONN1(2, k));
scanf("%" NAG_IFMT "", &CONN1(3, k));
scanf("%" NAG_IFMT "", &reftk);
scanf("%*[^\n] ");

reft1[k - 1] = 1;
reft2[k - 1] = 2;
}
scanf(" ' %1s '", pmesh);
scanf("%*[^\n] ");

/* the edges of the boundary */

ind = 0;

for (i = 1; i <= imaxm1; ++i) {
++ind;
EDGE1(1, ind) = i;
EDGE1(2, ind) = i + 1;
EDGE1(3, ind) = 1;
}

for (i = 1; i <= jmaxm1; ++i) {
++ind;
EDGE1(1, ind) = i * imax;
EDGE1(2, ind) = (i + 1) * imax;
EDGE1(3, ind) = 1;
}

for (i = 1; i <= imaxm1; ++i) {
++ind;
EDGE1(1, ind) = imax * jmax - i + 1;
EDGE1(2, ind) = imax * jmax - i;
EDGE1(3, ind) = 1;
}

for (i = 1; i <= jmaxm1; ++i) {
++ind;
EDGE1(1, ind) = (jmax - i) * imax + 1;
EDGE1(2, ind) = (jmax - i - 1) * imax + 1;
EDGE1(3, ind) = 1;
}

for (ktrans = 0; ktrans < 2; ++ktrans) {
/* Translation of the 1st domain to obtain the 2nd domain */
/* KTRANS = 0 leading to a domain overlapping */
/* KTRANS = 1 leading to a domain partition */

if (ktrans == 0) {
itrans = imax - 5;
jtrans = jmax - 3;
}
else {
itrans = imax - 1;
jtrans = 0;
}

itype[0] = 1;
TRANS(1, 1) = (double) itrans / (imax - 1.0);
TRANS(2, 1) = (double) jtrans / (jmax - 1.0);
itrace = 0;

/* nag_mesh2d_trans (d06dac).
* Generates a mesh resulting from an affine transformation
* of a given mesh
*/
nag_mesh2d_trans(mode, nv2, nedge2, nelt2, ntrans, itype, trans, coor1,
edge1, conn1, coor2, edge2, conn2, itrace, 0, &fail);
if (fail.code == NE_NOERROR) {
for (i = 1; i <= nedge2; ++i)
EDGE2(3, i) = 2;

/* Call to the restitching driver */

itrace = 0;
eps = 0.01;

/* nag_mesh2d_join (d06dbc).
* Joins together two given adjacent (possibly overlapping)
* meshes
*/
nag_mesh2d_join(eps, nv1, nelt1, nedge1, coor1, edge1, conn1, reft1,
nv2, nelt2, nedge2, coor2, edge2, conn2, reft2, &nv3,
&nelt3, &nedge3, coor3, edge3, conn3, reft3, itrace,
0, &fail);
if (fail.code == NE_NOERROR) {
if (pmesh[0] == 'N') {
if (ktrans == 0) {
printf("The restitched mesh characteristics\n");
printf("in the overlapping case\n");
}
else {
printf("in the partition case\n");
}
printf(" nv    =%6" NAG_IFMT "\n", nv3);
printf(" nelt  =%6" NAG_IFMT "\n", nelt3);
printf(" nedge =%6" NAG_IFMT "\n", nedge3);
}
else if (pmesh[0] == 'Y') {
/* Output the mesh to view it using the
NAG Graphics Library */

printf(" %10" NAG_IFMT "%10" NAG_IFMT "%10" NAG_IFMT "\n", nv3,
nelt3, nedge3);

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

for (k = 1; k <= nelt3; ++k)
printf(" %10" NAG_IFMT "%10" NAG_IFMT "%10" NAG_IFMT ""
"%10" NAG_IFMT "\n", CONN3(1, k), CONN3(2, k),
CONN3(3, k), reft3[k - 1]);

for (k = 1; k <= nedge3; ++k)
printf(" %10" NAG_IFMT "%10" NAG_IFMT "%10" NAG_IFMT "\n",
EDGE3(1, k), EDGE3(2, k), EDGE3(3, k));
}
else {
printf("Problem with the printing option Y or N\n");
exit_status = -1;
goto END;
}
}
else {
printf("Error from nag_mesh2d_join (d06dbc).\n%s\n", fail.message);
exit_status = 1;
goto END;
}
}
else {
printf("Error from nag_mesh2d_trans (d06dac).\n%s\n", fail.message);
exit_status = 1;
goto END;
}
}

END:
NAG_FREE(coor1);
NAG_FREE(coor2);
NAG_FREE(coor3);
NAG_FREE(trans);
NAG_FREE(conn1);
NAG_FREE(conn2);
NAG_FREE(conn3);
NAG_FREE(edge1);
NAG_FREE(edge2);
NAG_FREE(edge3);
NAG_FREE(itype);
NAG_FREE(reft1);
NAG_FREE(reft2);
NAG_FREE(reft3);

return exit_status;
}

int ex2(void)
{
const Integer nvmax = 900, nedmx = 200, neltmx = 2 * nvmax + 5,
ntrans = 1, nus = 0, nvint = 0, nvfix = 0;
static double ruser[1] = { -1.0 };
double eps;
Integer exit_status, i, itrace, j, k, l, ncomp, nedge1, nedge2, nedge3;
Integer nedge4, nedge5, nelt1, nelt2, nelt3, nelt4, nelt5, nlines;
Integer npropa, nqint, nv1, nv2, nv3, nv4, nv5, nvb1, nvb2, mode;
char pmesh[2];
double *coor1 = 0, *coor2 = 0, *coor3 = 0, *coor4 = 0, *coor5 = 0;
double *coorch = 0, *coorus = 0, *rate = 0, *trans = 0, *weight = 0;
Integer *conn1 = 0, *conn2 = 0, *conn3 = 0, *conn4 = 0, *conn5 = 0;
Integer *edge1 = 0, *edge2 = 0, *edge3 = 0, *edge4 = 0, *edge5 = 0;
Integer *itype = 0, *lcomp = 0, *lined = 0, *nlcomp = 0, *numfix = 0;
Integer *reft1 = 0, *reft2 = 0, *reft3 = 0, *reft4 = 0, *reft5 = 0;
NagError fail;
Nag_Comm comm;

INIT_FAIL(fail);

/* For communication with user-supplied functions: */
comm.user = ruser;

exit_status = 0;

printf("\nExample 2\n\n");

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

/* Build the mesh of the 1st domain */
/* Initialize boundary mesh inputs: */
/* the number of line and of the characteristic points of */
/* the boundary mesh */
scanf("%" NAG_IFMT "", &nlines);
scanf("%*[^\n] ");

/* Allocate memory */

if (!(coor1 = NAG_ALLOC(2 * nvmax, double)) ||
!(coor2 = NAG_ALLOC(2 * nvmax, double)) ||
!(coor3 = NAG_ALLOC(2 * nvmax, double)) ||
!(coor4 = NAG_ALLOC(2 * nvmax, double)) ||
!(coor5 = NAG_ALLOC(2 * nvmax, double)) ||
!(coorch = NAG_ALLOC(2 * nlines, double)) ||
!(coorus = NAG_ALLOC(1, double)) ||
!(rate = NAG_ALLOC(nlines, double)) ||
!(trans = NAG_ALLOC(6 * ntrans, double)) ||
!(weight = NAG_ALLOC(1, double)) ||
!(conn1 = NAG_ALLOC(3 * neltmx, Integer)) ||
!(conn2 = NAG_ALLOC(3 * neltmx, Integer)) ||
!(conn3 = NAG_ALLOC(3 * neltmx, Integer)) ||
!(conn4 = NAG_ALLOC(3 * neltmx, Integer)) ||
!(conn5 = NAG_ALLOC(3 * neltmx, Integer)) ||
!(edge1 = NAG_ALLOC(3 * nedmx, Integer)) ||
!(edge2 = NAG_ALLOC(3 * nedmx, Integer)) ||
!(edge3 = NAG_ALLOC(3 * nedmx, Integer)) ||
!(edge4 = NAG_ALLOC(3 * nedmx, Integer)) ||
!(edge5 = NAG_ALLOC(3 * nedmx, Integer)) ||
!(itype = NAG_ALLOC(ntrans, Integer)) ||
!(lcomp = NAG_ALLOC(nlines, Integer)) ||
!(lined = NAG_ALLOC(4 * nlines, Integer)) ||
!(numfix = NAG_ALLOC(1, Integer)) ||
!(reft1 = NAG_ALLOC(2 * nvmax + 5, Integer)) ||
!(reft2 = NAG_ALLOC(2 * nvmax + 5, Integer)) ||
!(reft3 = NAG_ALLOC(2 * nvmax + 5, Integer)) ||
!(reft4 = NAG_ALLOC(2 * nvmax + 5, Integer)) ||
!(reft5 = NAG_ALLOC(2 * nvmax + 5, Integer)))
{
printf("Allocation failure\n");
exit_status = -1;
goto END;
}

/* Characteristic points of the boundary geometry */

for (j = 1; j <= nlines; ++j) {
scanf("%lf", &COORCH(1, j));
}
scanf("%*[^\n] ");

for (j = 1; j <= nlines; ++j) {
scanf("%lf", &COORCH(2, j));
}
scanf("%*[^\n] ");

/* The lines of the boundary mesh */

for (j = 1; j <= nlines; ++j) {
for (i = 1; i <= 4; ++i)
scanf("%" NAG_IFMT "", &LINED(i, j));
scanf("%lf", &rate[j - 1]);
}
scanf("%*[^\n] ");

/* The number of connected components */
/* on the boundary and their data */
scanf("%" NAG_IFMT "", &ncomp);
scanf("%*[^\n] ");

/* Allocate memory */

if (!(nlcomp = NAG_ALLOC(ncomp, Integer)))
{
printf("Allocation failure\n");
exit_status = -1;
goto END;
}

j = 1;

for (i = 1; i <= ncomp; ++i) {
scanf("%" NAG_IFMT "", &nlcomp[i - 1]);
scanf("%*[^\n] ");
l = j + abs(nlcomp[i - 1]) - 1;
for (k = j; k <= l; ++k)
scanf("%" NAG_IFMT "", &lcomp[k - 1]);
scanf("%*[^\n] ");
j += abs(nlcomp[i - 1]);
}

itrace = 0;

/* Call to the 2D boundary mesh generator */

/* nag_mesh2d_bound (d06bac).
* Generates a boundary mesh
*/
nag_mesh2d_bound(nlines, coorch, lined, fbnd, coorus, nus, rate, ncomp,
nlcomp, lcomp, nvmax, nedmx, &nvb1, coor1, &nedge1,
edge1, itrace, 0, &comm, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_mesh2d_bound (d06bac).\n%s\n", fail.message);
exit_status = 1;
goto END;
}

/* Generate mesh using Delaunay-Voronoi method */

/* Initialize mesh control parameters */

itrace = 0;
npropa = 1;

/* nag_mesh2d_delaunay (d06abc).
* Generates a two-dimensional mesh using a Delaunay-Voronoi
* process
*/
nag_mesh2d_delaunay(nvb1, nvint, nvmax, nedge1, edge1, &nv1, &nelt1, coor1,
conn1, weight, npropa, itrace, 0, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_mesh2d_delaunay (d06abc).\n%s\n", fail.message);
exit_status = 1;
goto END;
}

for (k = 1; k <= nelt1; ++k)
reft1[k - 1] = 1;

/* Call the smoothing routine */

nqint = 10;
/* nag_mesh2d_smooth (d06cac).
* Uses a barycentering technique to smooth a given mesh
*/
nag_mesh2d_smooth(nv1, nelt1, nedge1, coor1, edge1, conn1, nvfix, numfix,
itrace, 0, nqint, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_mesh2d_smooth (d06cac).\n%s\n", fail.message);
exit_status = 1;
goto END;
}

/* Build the mesh of the 2nd domain */
scanf("%" NAG_IFMT "", &nlines);
scanf("%*[^\n] ");

/* Characteristic points of the boundary geometry */
for (j = 1; j <= nlines; ++j)
scanf("%lf", &COORCH(1, j));
scanf("%*[^\n] ");
for (j = 1; j <= nlines; ++j)
scanf("%lf", &COORCH(2, j));
scanf("%*[^\n] ");

/* The lines of the boundary mesh */

for (j = 1; j <= nlines; ++j) {
for (i = 1; i <= 4; ++i)
scanf("%" NAG_IFMT "", &LINED(i, j));
scanf("%lf", &rate[j - 1]);
}
scanf("%*[^\n] ");

/* The number of connected components */
/* to the boundary and their data */
scanf("%" NAG_IFMT "", &ncomp);
scanf("%*[^\n] ");

j = 1;
for (i = 1; i <= ncomp; ++i) {
scanf("%" NAG_IFMT "", &nlcomp[i - 1]);
scanf("%*[^\n] ");

for (k = j; k <= j + abs(nlcomp[i - 1]) - 1; ++k)
scanf("%" NAG_IFMT "", &lcomp[k - 1]);
scanf("%*[^\n] ");
j += abs(nlcomp[i - 1]);
}
scanf(" ' %1s '", pmesh);
scanf("%*[^\n] ");

itrace = 0;

/* Call to the 2D boundary mesh generator */

/* nag_mesh2d_bound (d06bac), see above. */
nag_mesh2d_bound(nlines, coorch, lined, fbnd, coorus, nus, rate, ncomp,
nlcomp, lcomp, nvmax, nedmx, &nvb2, coor2, &nedge2, edge2,
itrace, 0, &comm, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_mesh2d_bound (d06bac).\n%s\n", fail.message);
exit_status = 1;
goto END;
}

/* Generate mesh using the advancing front method */

itrace = 0;

/* nag_mesh2d_front (d06acc).
* Generates a two-dimensional mesh using an Advancing-front
* method
*/
nag_mesh2d_front(nvb2, nvint, nvmax, nedge2, edge2, &nv2, &nelt2, coor2,
conn2, weight, itrace, 0, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_mesh2d_front (d06acc).\n%s\n", fail.message);
exit_status = 1;
goto END;
}

for (k = 1; k <= nelt2; ++k)
reft2[k - 1] = 2;

/* Rotation of the 2nd domain mesh */
/* to produce the 3rd mesh domain */

itype[0] = 3;
TRANS(1, 1) = 6.0;
TRANS(2, 1) = -1.0;
TRANS(3, 1) = -90.0;
itrace = 0;
mode = 0;

/* nag_mesh2d_trans (d06dac), see above. */
nag_mesh2d_trans(mode, nv2, nedge2, nelt2, ntrans, itype, trans, coor2,
edge2, conn2, coor3, edge3, conn3, itrace, 0, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_mesh2d_trans (d06dac).\n%s\n", fail.message);
exit_status = 1;
goto END;
}

nv3 = nv2;
nelt3 = nelt2;
nedge3 = nedge2;

for (k = 1; k <= nelt3; ++k)
reft3[k - 1] = 3;

/* Restitching meshes 1 and 2 to form mesh 4 */

eps = 0.001;
itrace = 0;

/* nag_mesh2d_join (d06dbc), see above. */
nag_mesh2d_join(eps, nv1, nelt1, nedge1, coor1, edge1, conn1, reft1, nv2,
nelt2, nedge2, coor2, edge2, conn2, reft2, &nv4, &nelt4,
&nedge4, coor4, edge4, conn4, reft4, itrace, 0, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_mesh2d_join (d06dbc).\n%s\n", fail.message);
exit_status = 1;
goto END;
}

/* Restitching meshes 3 and 4 to form mesh 5 */

itrace = 0;

/* nag_mesh2d_join (d06dbc), see above. */
nag_mesh2d_join(eps, nv4, nelt4, nedge4, coor4, edge4, conn4, reft4, nv3,
nelt3, nedge3, coor3, edge3, conn3, reft3, &nv5, &nelt5,
&nedge5, coor5, edge5, conn5, reft5, itrace, 0, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_mesh2d_join (d06dbc).\n%s\n", fail.message);
exit_status = 1;
goto END;
}

if (pmesh[0] == 'N') {
printf("The restitched mesh characteristics\n");
printf(" nv    =%6" NAG_IFMT "\n", nv5);
printf(" nelt  =%6" NAG_IFMT "\n", nelt5);
printf(" nedge =%6" NAG_IFMT "\n", nedge5);
}
else if (pmesh[0] == 'Y') {
/* Output the mesh to view it using the NAG Graphics Library */

printf(" %10" NAG_IFMT "%10" NAG_IFMT "%10" NAG_IFMT "\n", nv5, nelt5,
nedge5);

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

for (k = 1; k <= nelt5; ++k)
printf("%10" NAG_IFMT "%10" NAG_IFMT "%10" NAG_IFMT "%10" NAG_IFMT "\n",
CONN5(1, k), CONN5(2, k), CONN5(3, k), reft5[k - 1]);

for (k = 1; k <= nedge5; ++k)
printf(" %10" NAG_IFMT "%10" NAG_IFMT "%10" NAG_IFMT "\n",
EDGE5(1, k), EDGE5(2, k), EDGE5(3, k));
}
else {
printf("Problem with the printing option Y or N\n");
}

END:
NAG_FREE(coor1);
NAG_FREE(coor2);
NAG_FREE(coor3);
NAG_FREE(coor4);
NAG_FREE(coor5);
NAG_FREE(coorch);
NAG_FREE(coorus);
NAG_FREE(rate);
NAG_FREE(trans);
NAG_FREE(weight);
NAG_FREE(conn1);
NAG_FREE(conn2);
NAG_FREE(conn3);
NAG_FREE(conn4);
NAG_FREE(conn5);
NAG_FREE(edge1);
NAG_FREE(edge2);
NAG_FREE(edge3);
NAG_FREE(edge4);
NAG_FREE(edge5);
NAG_FREE(itype);
NAG_FREE(lcomp);
NAG_FREE(lined);
NAG_FREE(nlcomp);
NAG_FREE(numfix);
NAG_FREE(reft1);
NAG_FREE(reft2);
NAG_FREE(reft3);
NAG_FREE(reft4);
NAG_FREE(reft5);

return exit_status;
}

double NAG_CALL fbnd(Integer i, double x, double y, Nag_Comm *pcomm)
{

if (pcomm->user[0] == -1.0) {
printf("(User-supplied callback fbnd, first invocation.)\n");
pcomm->user[0] = 0.0;
}

ret_val = 0.0;
switch (i) {
case 1:

/* inner circle */

x0 = 0.0;
y0 = 0.0;
ret_val = (x - x0) * (x - x0) + (y - y0) * (y - y0) - radius2;
break;

case 2:

/* outer circle */

x0 = 0.0;
y0 = 0.0;