int create_hierarchy(const int nLevel, /* in */ prealmatrix coordinates, /* in / out */ pindexmatrix elements, /* in / out */ prealvector material, /* in / out */ pindexmatrix elements2edges, /* in */ pindexmatrix *f2s, /* out */ const int nBdry, /* in */ pcindexvector bdrytyp, /* in */ pindexmatrix *bdrylist, /* in / out */ pindexvector *bdry2edgeslist, /* in / out */ pcrs *A, /* in / out */ pindexvector *fixed) /* out */ { int i; pcoo S = new_coo(1,1,1); pindexmatrix edgeno; f2s = (pindexmatrix*) malloc((nLevel-1)*sizeof(pindexmatrix)); fixed = (pindexvector*) malloc(nLevel*sizeof(pindexvector)); edgeno = new_indexmatrix(0,0); if (!f2s || !fixed){ free(f2s); free(fixed); return 0; } /* Store fixed for coarsest mesh*/ getFixed(nBdry, bdrytyp, bdrylist, fixed[nLevel-1]); /* Refine mesh (nLevel-1) times */ for (i=nLevel-2; i>=0; i--){ refine_uniform(coordinates, elements, material, elements2edges, edgeno, bdrylist, bdry2edgeslist, nBdry); getFixed(nBdry, bdrytyp, bdrylist, fixed[i]); f2s[i] = edgeno; } if (!(A==NULL)){ A = (pcrs*) malloc(nLevel*sizeof(pcrs)); if (!A || !fixed){ free(A); free(fixed); return 0; } /* Build stiffness matrix for finest mesh */ buildStiffness(coordinates, elements, S); A[0] = new_crs(1,1,1); init_coo2crs(A[0], S); /* Build stiffness matrix for coarser meshes */ for (i=1; i<nLevel; i++){ buildStiffnessByInterpolation(A[i-1],A[i],f2s[i-1]); } } del_indexmatrix(edgeno); return 1; }
void refine_uniform(prealmatrix coordinates, /* in / out */ pindexmatrix elements, /* in / out */ prealvector material, /* in / out */ pindexmatrix elements2edges, /* in / out */ pindexmatrix edgeno, /* out */ pindexmatrix *bdrylist, /* in / out */ pindexvector *bdry2edgeslist, /* in / out */ const int nBdry){ /* in */ /* Allocate local variables */ int iBdry; index *B, *B2e, *nB, *nB2e; index nEdges, nTria, nCoord; index *E, *E2e, *nE, *nE2e, *nEno; real *M, *nM; real *C, *nC; index i, i0, i1, k, p; int isucc[3] = {1,2,0}, iprae[3] = {2,0,1}; prealmatrix new_coordinates; prealvector new_material; pindexmatrix new_elements, new_elements2edges, new_bdrylist, new_edgeno; pindexvector new_bdry2edgeslist; /* Check proper input */ assert(coordinates); assert(elements); assert(material); assert(elements2edges); assert(edgeno); assert(bdrylist); assert(nBdry); /* Set mesh sizes */ nCoord = coordinates->cols; /* Number of coordinates */ nTria = elements->cols; /* Number of triangles */ E2e = elements2edges->vals; nEdges = 0; /* Number of edges */ for (i=0 ; i<3*(elements2edges->cols); ++i) if ( E2e[i]> nEdges) nEdges = E2e[i]; nEdges+=1-INDEX_BASE; /* Allocate storage for refined mesh */ new_coordinates = new_realmatrix(2,nCoord+nEdges); new_elements = new_indexmatrix(3,4*nTria); new_material = new_realvector(4*nTria); new_elements2edges = new_indexmatrix(3,4*nTria); new_edgeno = new_indexmatrix(2,nEdges); /* Declare local variables for convinience */ C = coordinates->vals; nC = new_coordinates->vals; E = elements->vals; nE = new_elements->vals; M = material->vals; nM = new_material->vals; nE2e = new_elements2edges->vals; nEno = new_edgeno->vals; /* Get endpoints for each edge, i.e. compute edgeno */ for (i=0 ; i<nTria ; ++i){ for (k=0 ; k<3 ; ++k){ p=3*i+k; nEno[2*(E2e[p]-INDEX_BASE) ] = E[p]; nEno[2*(E2e[p]-INDEX_BASE)+1] = E[3*i+isucc[k]]; } } /* Copy old coordinates */ for (i=0 ; i<2*nCoord ; i++) nC[i] = C[i]; /* Compute new coordinates */ for (i=0 ; i<nEdges ; i++){ i0 = nEno[2*i] -INDEX_BASE; i1 = nEno[2*i+1]-INDEX_BASE; nC[2*nCoord+2*i ] = 0.5*(C[2*i0 ] + C[2*i1 ]); nC[2*nCoord+2*i+1] = 0.5*(C[2*i0+1] + C[2*i1+1]); } /* Loop over all elements */ for (i=0 ; i<nTria ; i++){ for (k=0 ; k<3 ; k++){ nE[12*i+3*k+0] = E[3*i+k]; nE[12*i+3*k+1] = nCoord + E2e[3*i+k]; nE[12*i+3*k+2] = nCoord + E2e[3*i+iprae[k]]; nE2e[12*i+3*k+0] = 2*E2e[3*i+k]-INDEX_BASE+ (E[3*i+k]>E[3*i+isucc[k]]); nE2e[12*i+3*k+1] = 2*nEdges+3*i+k+INDEX_BASE; nE2e[12*i+3*k+2] = 2*E2e[3*i+iprae[k]]-INDEX_BASE+ (E[3*i+k]>E[3*i+iprae[k]]); nM[4*i+k] = M[i]; } nE[12*i+ 9] = nCoord + E2e[3*i ]; nE[12*i+10] = nCoord + E2e[3*i+1]; nE[12*i+11] = nCoord + E2e[3*i+2]; nE2e[12*i+ 9] = 2*nEdges+3*i+1+INDEX_BASE; nE2e[12*i+10] = 2*nEdges+3*i+2+INDEX_BASE; nE2e[12*i+11] = 2*nEdges+3*i+0+INDEX_BASE; nM[4*i+3] = M[i]; } /* Refine boundary */ new_bdrylist = new_indexmatrix(0,0); new_bdry2edgeslist = new_indexvector(0); /* Loop over all boundary pieces */ for (iBdry=0 ; iBdry<nBdry ; iBdry++){ resize_indexmatrix(new_bdrylist,2,2*bdrylist[iBdry]->cols); resize_indexvector(new_bdry2edgeslist,2*bdrylist[iBdry]->cols); B = bdrylist[iBdry]->vals; B2e = bdry2edgeslist[iBdry]->vals; nB = new_bdrylist->vals; nB2e = new_bdry2edgeslist->vals; for (i=0 ; i<bdrylist[iBdry]->cols ; i++){ /* Refine bdrylist[iBdry]*/ nB[4*i ] = B[2*i]; nB[4*i+1] = nCoord+B2e[i]; nB[4*i+2] = nCoord+B2e[i]; nB[4*i+3] = B[2*i+1]; /* Refine bdry2edgeslist[iBdry]*/ nB2e[2*i ] = 2*B2e[i ] + (B[2*i ] > B[2*i+1]) - INDEX_BASE; nB2e[2*i+1] = 2*B2e[i ] + (B[2*i+1] > B[2*i ]) - INDEX_BASE; } swap_indexmatrix(bdrylist[iBdry], new_bdrylist); swap_indexvector(bdry2edgeslist[iBdry], new_bdry2edgeslist); } swap_realmatrix(coordinates, new_coordinates); swap_realvector(material, new_material); swap_indexmatrix(edgeno, new_edgeno); swap_indexmatrix(elements, new_elements); swap_indexmatrix(elements2edges, new_elements2edges); del_realmatrix(new_coordinates); del_realvector(new_material); del_indexmatrix(new_edgeno); del_indexmatrix(new_elements); del_indexmatrix(new_elements2edges); del_indexmatrix(new_bdrylist); del_indexvector(new_bdry2edgeslist); }
int main(int argc, char **argv) { int nItCG, nLevel = 2; long TIME[9]; int nBdry = 2; pcoo S = new_coo(1,1,1); pcrs A = new_crs(1,1,1); pindexmatrix edgeno = new_indexmatrix(0,0); pindexmatrix *s2p = NULL; pindexvector *fixedNodes = NULL; pindexvector material; prealmatrix coordinates; pindexmatrix elements; pindexmatrix elements2edges; pindexvector bdrytyp = new_indexvector(2); pindexmatrix bdrylist[2]; pindexvector bdry2edgeslist[2]; prealvector rhs; prealvector sol; /* Number of refinements */ if (argc>1){ if (atoi(argv[1]) < 12) nLevel = atoi(argv[1]); } /* Load geometry */ material = load_indexvector("./Tests/Example1/material.dat"); coordinates = load_realmatrix("./Tests/Example1/coordinates.dat",(index)2,1); elements = load_indexmatrix("./Tests/Example1/elements.dat",3,1); elements2edges = load_indexmatrix("./Tests/Example1/elements2edges.dat",3,1); bdrytyp->vals[0] = 0; bdrytyp->vals[1] = 1; bdrylist[0] = load_indexmatrix("./Tests/Example1/Dirichlet.dat",2,1); bdrylist[1] = load_indexmatrix("./Tests/Example1/Neumann.dat",2,1); bdry2edgeslist[0] = load_indexvector("./Tests/Example1/Dirichlet2edges.dat"); bdry2edgeslist[1] = load_indexvector("./Tests/Example1/Neumann2edges.dat"); /* Show geometry */ printf("====================\n"); printf("coordinates:\n"); printf("====================\n"); print_realmatrix(coordinates); printf("====================\n"); printf("elements:\n"); printf("====================\n"); print_indexmatrix(elements); printf("====================\n"); printf("elements2edges:\n"); printf("====================\n"); print_indexmatrix(elements2edges); printf("====================\n"); printf("material:\n"); printf("====================\n"); print_indexvector(material); printf("====================\n"); printf("bdrylist:\n"); printf("====================\n"); print_indexmatrix(bdrylist[0]); printf("--------------------\n"); print_indexmatrix(bdrylist[1]); printf("====================\n"); printf("bdry2edgeslist:\n"); printf("====================\n"); print_indexvector(bdry2edgeslist[0]); printf("--------------------\n"); print_indexvector(bdry2edgeslist[1]); printf("====================\n"); TIME[0] = clock(); /* Refine mesh uniformly */ create_hierarchy(nLevel, /* in */ coordinates, /* in / out */ elements, /* in / out */ material, /* in / out */ elements2edges, /* in */ s2p, /* out */ nBdry, /* in */ bdrytyp, /* in */ bdrylist, /* in / out */ bdry2edgeslist, /* in / out */ NULL, /* in / out */ fixedNodes); /* in / out */ TIME[1] = clock(); write_realmatrix("./Tests/Example1/coordinates_fine.dat",coordinates,1); write_indexmatrix("./Tests/Example1/elements_fine.dat",elements,1); write_indexmatrix("./Tests/Example1/elements2edges_fine.dat",elements,1); write_indexvector("./Tests/Example1/material_fine.dat",material); write_indexmatrix("./Tests/Example1/Dirichlet_fine.dat",bdrylist[0],1); write_indexmatrix("./Tests/Example1/Neumann_fine.dat",bdrylist[1],1); write_indexvector("./Tests/Example1/Dirichlet2edges_fine.dat",bdry2edgeslist[0]); write_indexvector("./Tests/Example1/Neumann2edges_fine.dat",bdry2edgeslist[1]); rhs = new_realvector(coordinates->cols); sol = new_realvector(coordinates->cols); TIME[2] = clock(); buildStiffness(coordinates, elements, S); TIME[3] = clock(); init_coo2crs(A, S); TIME[4] = clock(); buildRhs(coordinates, elements, VolForce, rhs); copy_realvector(sol, rhs); setDirichletData2Rhs(coordinates, fixedNodes[0], uD, sol); TIME[5] = clock(); nItCG = cgcrs_constrains(A,sol,rhs, fixedNodes[0],1e-6,coordinates->cols); printf("No. iterations %i\n", nItCG); TIME[6] = clock(); write_realvector("./Tests/Example1/sol_fine.dat",sol); TIME[7] = clock(); printf("---------------------\n"); printf("Time for refinement = %i ms\n", ELAPSED(TIME[0],TIME[1])); printf("Time for saving ref. mesh = %i ms\n", ELAPSED(TIME[1],TIME[2])); printf("Time for assembling = %i ms\n", ELAPSED(TIME[2],TIME[3])); printf("Time for COO -> CRS = %i ms\n", ELAPSED(TIME[3],TIME[4])); printf("Time for RHS = %i ms\n", ELAPSED(TIME[4],TIME[5])); printf("Time for solving = %i ms\n", ELAPSED(TIME[5],TIME[6])); printf("Time store solution = %i ms\n\n", ELAPSED(TIME[6],TIME[7])); printf("Degrees of elements / freedom %lu / %lu\n", elements->cols, coordinates->cols); printf("---------------------\n"); del_coo(S); del_crs(A); del_realvector(rhs); del_realvector(sol); del_indexmatrix(edgeno); del_realmatrix(coordinates); del_indexmatrix(elements); del_indexmatrix(elements2edges); del_indexvector(material); return 0; }