/* nag_mesh2d_join (d06dbc) Example Program. * * Copyright 2001 Numerical Algorithms Group. * * Mark 7, 2001. * Mark 7b revised, 2004. */ #include #include #include #include #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 EDGE4(I, J) edge4[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 CONN2(I, J) conn2[3*((J) -1)+(I) -1] #define CONN3(I, J) conn3[3*((J) -1)+(I) -1] #define CONN4(I, J) conn4[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 COOR2(I, J) coor2[2*((J) -1)+(I) -1] #define COOR3(I, J) coor3[2*((J) -1)+(I) -1] #define COOR4(I, J) coor4[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] #define COORUS(I, J) coorus[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("%ld", &nv1); scanf("%ld", &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("%ld", &CONN1(1, k)); scanf("%ld", &CONN1(2, k)); scanf("%ld", &CONN1(3, k)); scanf("%ld", &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 =%6ld\n", nv3); printf(" nelt =%6ld\n", nelt3); printf(" nedge =%6ld\n", nedge3); } else if (pmesh[0] == 'Y') { /* Output the mesh to view it using the NAG Graphics Library */ printf(" %10ld%10ld%10ld\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(" %10ld%10ld%10ld" "%10ld\n", CONN3(1, k), CONN3(2, k), CONN3(3, k), reft3[k - 1]); for (k = 1; k <= nedge3; ++k) printf(" %10ld%10ld%10ld\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 */ /* Initialise boundary mesh inputs: */ /* the number of line and of the characteristic points of */ /* the boundary mesh */ scanf("%ld", &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("%ld", &LINED(i, j)); scanf("%lf", &rate[j - 1]); } scanf("%*[^\n] "); /* The number of connected components */ /* on the boundary and their data */ scanf("%ld", &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("%ld", &nlcomp[i - 1]); scanf("%*[^\n] "); l = j + abs(nlcomp[i - 1]) - 1; for (k = j; k <= l; ++k) scanf("%ld", &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 */ /* Initialise 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("%ld", &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("%ld", &LINED(i, j)); scanf("%lf", &rate[j - 1]); } scanf("%*[^\n] "); /* The number of connected components */ /* to the boundary and their data */ scanf("%ld", &ncomp); scanf("%*[^\n] "); j = 1; for (i = 1; i <= ncomp; ++i) { scanf("%ld", &nlcomp[i - 1]); scanf("%*[^\n] "); for (k = j; k <= j+abs(nlcomp[i-1])-1; ++k) scanf("%ld", &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 =%6ld\n", nv5); printf(" nelt =%6ld\n", nelt5); printf(" nedge =%6ld\n", nedge5); } else if (pmesh[0] == 'Y') { /* Output the mesh to view it using the NAG Graphics Library */ printf(" %10ld%10ld%10ld\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("%10ld%10ld%10ld%10ld\n", CONN5(1, k), CONN5(2, k), CONN5(3, k), reft5[k - 1]); for (k = 1; k <= nedge5; ++k) printf(" %10ld%10ld%10ld\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) { double radius2, x0, y0, ret_val; 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; radius2 = 1.0; ret_val = (x-x0)*(x-x0) + (y-y0)*(y-y0) - radius2; break; case 2: /* outer circle */ x0 = 0.0; y0 = 0.0; radius2 = 5.0; ret_val = (x-x0)*(x-x0) + (y-y0)*(y-y0) - radius2; break; } return ret_val; }