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; }