int main(int argc, char **argv) { if (argc!=4) { (void) fprintf(stderr, "Usage: ./main N maxit print(1/0)\n"); return 1; } int N = atoi(argv[1]); ///< Nodes in each dimension int maxit = atoi(argv[2]); ///< Maximum iteration number for CG int print = atoi(argv[3]); ///< Print output: set to 0 for big N index i; real alpha = 1., beta = 0.; ///< gecrsmv parameters real tol = 1e-8; ///< CG tolerance index it; /// Assemble and print stiffness matrix pcrs A = new_crs(0, 0, 0); assemble_laplace(A, N); if (print) { (void) printf("A =\n"); printdense_crs(A); } /// Set up, perform and print y <- alpha*A*x+beta*y prealvector x = new_realvector(N*N); prealvector y = new_realvector(N*N); transpose t = notrans; for (i=INDEX_BASE; i<x->length+INDEX_BASE; ++i) { setentry_realvector(x, i, 1.); } gecrsmv(t, alpha, A, x, beta, y); if (print) { (void) printf("y = A*ones =\n"); print_realvector(y); } /// Apply CG solver it = cgcrs(A, y, x, tol, maxit); (void) printf("Solution after %ld iterations\n", it); if (print) { (void) printf("x =\n"); print_realvector(y); } del_crs(A); del_realvector(x); del_realvector(y); return 0; }
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); }
index cgcoo(pccoo A, prealvector x, pcrealvector b, real tol, index maxit) { index i; real residual; prealvector r, p, Ap; transpose t; /* Input parsing */ assert(A); assert(x); assert(b); assert(A->numc==x->length); assert(x->length==b->length); assert(A->numr==A->numc); r = new_realvector(x->length); p = new_realvector(x->length); Ap = new_realvector(x->length); /* Initial residual */ copy_realvector(r, b); t = notrans; gecoomv(t, -1., A, x, 1., r); copy_realvector(p, r); residual = nrm2_realvector(r); for (i=0; i<=maxit; ++i) { real ak, bk, residual_old; if (residual<=tol) { #ifdef VERBOSE (void) printf("cg: r = %.16f\n", residual); #endif del_realvector(r); del_realvector(p); del_realvector(Ap); return i; } /* alpha_k */ ak = residual*residual; gecoomv(t, 1., A, p, 0., Ap); ak /= dot_realvector(p, Ap); /* Update x_k and r_k */ axpy_realvector(ak, p, x); axpy_realvector(-ak, Ap, r); /* Update p_k */ residual_old = residual; residual = nrm2_realvector(r); bk = residual*residual/(residual_old*residual_old); scal_realvector(bk, p); axpy_realvector(1., r, p); } fprintf(stderr, "Max iterations reached: maxit = %ld, r = %.16f\n", maxit, residual); del_realvector(r); del_realvector(p); del_realvector(Ap); return maxit; }
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; }