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; }
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 buildStiffnessByInterpolation(pcrs Ain, pcrs Aout, pindexmatrix s2p) { index i, j, nS, nH, nE, nz; pcoo AxP_coo; pcoo S; pcrs AxP_crs; nH = Ain->numc; /* Huge dimension */ nE = (s2p->cols); /* Number of son -> parents relations */ nS = nH - nE; /* Small dimension */ /* Let interpolation operator be P = [P_c, P_f] * and A = [A_cc, A_cf / A_fc, A_ff] * * Notice, A is expected to be symmetric and P_c is the identity matrix. */ /* Compute [A_cf / A_ff] * P_f */ AxP_coo = new_coo( 2 * ( Ain->rowptr[nH] - Ain->rowptr[nS] ), nH, nS); nz = 0; for (i=0; i< nE; i++){ for(j = Ain->rowptr[nS+i]; j < Ain->rowptr[nS+i+1]; j++){ AxP_coo->vals[nz] = 0.5 * Ain->vals[j]; AxP_coo->cols[nz] = s2p->vals[2*i ]; AxP_coo->rows[nz] = Ain->colind[j]; nz++; AxP_coo->vals[nz] = 0.5 * Ain->vals[j]; AxP_coo->cols[nz] = s2p->vals[2*i+1 ]; AxP_coo->rows[nz] = Ain->colind[j]; nz++; } } /* Convert to crs format */ AxP_crs= new_crs(1,1,1); init_coo2crs(AxP_crs, AxP_coo); del_coo(AxP_coo); /* Allocate memory to store P^T * A * P in coo format */ nz = Ain->rowptr[nS] + 2 * AxP_crs->rowptr[nH]; S = new_coo(Ain->rowptr[nS],nS,nS); /* Copy entries of A_cc to S */ nz = 0; for (i=0; i< nS; i++){ for(j = Ain->rowptr[i]; j < Ain->rowptr[i+1]; ++j){ if (Ain->colind[j]-INDEX_BASE<nS){ S->vals[nz] = Ain->vals[j]; S->rows[nz] = i+INDEX_BASE; S->cols[nz] = Ain->colind[j]; nz++; } } } resize_coo(S,nz+ 2 * AxP_crs->rowptr[nH],nS,nS); /* Copy entries of A_cf * P_f and (A_cf * P_f)^T to S */ for (i=0; i< nS; i++){ for(j = AxP_crs->rowptr[i] ; j < AxP_crs->rowptr[i+1]; j++){ S->vals[nz] = AxP_crs->vals[j]; S->cols[nz] = i+INDEX_BASE; S->rows[nz] = AxP_crs->colind[j]; nz++; S->vals[nz] = AxP_crs->vals[j]; S->cols[nz] = AxP_crs->colind[j]; S->rows[nz] = i+INDEX_BASE; nz++; } } /* Compute P_f^T * A_cf * P_f and store to S */ for (i=0; i< nE; i++){ for( j = AxP_crs->rowptr[nS+i] ; j < AxP_crs->rowptr[nS+i+1] ; j++){ S->vals[nz] = 0.5 * AxP_crs->vals[j]; S->rows[nz] = s2p->vals[2*i ]; S->cols[nz] = AxP_crs->colind[j]; nz++; S->vals[nz] = 0.5 * AxP_crs->vals[j]; S->rows[nz] = s2p->vals[2*i+1]; S->cols[nz] = AxP_crs->colind[j]; nz++; } } /* Convert to crs format */ del_crs(AxP_crs); init_coo2crs(Aout, S); del_coo(S); return; }
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; }