int main(int argc, char* argv[]) { if (argc != 2) fprintf(stderr, "Usage: Requires number of threads."); thread_count = atoi(argv[1]); Lab3LoadInput(&A, &size); x = CreateVec(size); double start, end; int i = 0; GET_TIME(start); # pragma omp parallel num_threads(thread_count) \ shared(A) { gaussian_elimination(); jordan_elimination(); # pragma omp for for (i = 0; i < size; ++i) { x[i] = A[i][size] / A[i][i]; } } GET_TIME(end); Lab3SaveOutput(x, size, end-start); printf("time is: %e\n", end-start); DestroyVec(x); DestroyMat(A, size); return EXIT_SUCCESS; }
int main(int argc, char* argv[]) { int i, j, k, size; double** Au; double* X; double temp, error, Xnorm; int* index; FILE* fp; /*Load the datasize and verify it*/ Lab3LoadInput(&Au, &size); if ((fp = fopen("data_output","r")) == NULL){ printf("Fail to open the result data file!\n"); return 2; } fscanf(fp, "%d\n\n", &i); if (i != size){ printf("The problem size of the input file and result file does not match!\n"); return -1; } /*Calculate the solution by serial code*/ X = CreateVec(size); index = malloc(size * sizeof(int)); for (i = 0; i < size; ++i) index[i] = i; if (size == 1) X[0] = Au[0][1] / Au[0][0]; else{ /*Gaussian elimination*/ for (k = 0; k < size - 1; ++k){ /*Pivoting*/ temp = 0; for (i = k, j = 0; i < size; ++i) if (temp < Au[index[i]][k] * Au[index[i]][k]){ temp = Au[index[i]][k] * Au[index[i]][k]; j = i; } if (j != k)/*swap*/{ i = index[j]; index[j] = index[k]; index[k] = i; } /*calculating*/ for (i = k + 1; i < size; ++i){ temp = Au[index[i]][k] / Au[index[k]][k]; for (j = k; j < size + 1; ++j) Au[index[i]][j] -= Au[index[k]][j] * temp; } } /*Jordan elimination*/ for (k = size - 1; k > 0; --k){ for (i = k - 1; i >= 0; --i ){ temp = Au[index[i]][k] / Au[index[k]][k]; Au[index[i]][k] -= temp * Au[index[k]][k]; Au[index[i]][size] -= temp * Au[index[k]][size]; } } /*solution*/ for (k=0; k< size; ++k) X[k] = Au[index[k]][size] / Au[index[k]][k]; } /*compare the solution*/ error = 0; Xnorm = 0; for (i = 0; i < size; ++i){ fscanf(fp, "%lf\t", &temp); error += (temp-X[i]) * (temp-X[i]); Xnorm += X[i]*X[i]; } error = sqrt(error); Xnorm = sqrt(Xnorm); printf("The relative error to the reference solution is %e\n", error / Xnorm); if (error / Xnorm <= TOL) printf("Congratulation!!! Your result is accepted!\n"); else printf("Sorry, your result is wrong.\n"); fclose(fp); DestroyVec(X); DestroyMat(Au, size); free(index); return 0; }
Geometry CreateGeometry(int N[3], double h[3], int Npml[3], int Nc, int LowerPML, double *eps, double *epsI, double *fprof, double wa, double y){ int i; Geometry geo = (Geometry) malloc(sizeof(struct Geometry_s)); geo->Nc = Nc; geo->LowerPML = LowerPML; geo->interference = 0.0; // default no interference for(i=0; i<3; i++){ geo->h[i] = h[i]; geo->Npml[i] = Npml[i]; } CreateGrid(&geo->gN, N, geo->Nc, 2); CreateGrid(&geo->gM, N, 1, 1); // 3/3/14: set M = N as per Steven CreateVec(2*Nxyzc(geo)+2, &geo->vepspml); int manual_epspml = 0; PetscOptionsGetInt(PETSC_NULL,PETSC_NULL,"-manual_epspml", &manual_epspml, NULL); if(manual_epspml == 0){ Vecfun pml; CreateVecfun(&pml,geo->vepspml); for(i=pml.ns; i<pml.ne; i++){ Point p; CreatePoint_i(&p, i, &geo->gN); project(&p, 3); dcomp eps_geoal; eps_geoal = pmlval(xyzc(&p), N, geo->Npml, geo->h, geo->LowerPML, 0); setr(&pml, i, p.ir? cimag(eps_geoal) : creal(eps_geoal) ); } DestroyVecfun(&pml); } CreateVec(Mxyz(geo), &geo->vMscratch[0]); for(i=0; i<SCRATCHNUM; i++){ geo->vNhscratch[i] = 0; // allows checking whether vN created or not if(i>0)VecDuplicate(geo->vMscratch[0], &geo->vMscratch[i]); } double *scratch; int ms, me; VecGetOwnershipRange(geo->vMscratch[0], &ms, &me); if( !manual_epspml){ VecGetArray(geo->vMscratch[0], &scratch); for(i=ms; i<me;i++) scratch[i-ms] = eps[i-ms]; VecRestoreArray(geo->vMscratch[0], &scratch); } CreateVec(2*Nxyzc(geo)+2, &geo->vH); VecDuplicate(geo->vH, &geo->veps); VecDuplicate(geo->vH, &geo->vIeps); for(i=0; i<SCRATCHNUM; i++) VecDuplicate(geo->vH, &geo->vscratch[i]); VecSet(geo->vH, 1.0); if( !manual_epspml){ VecShift(geo->vMscratch[0], -1.0); //hack, for background dielectric InterpolateVec(geo, geo->vMscratch[0], geo->vscratch[1]); VecShift(geo->vscratch[1], 1.0); VecPointwiseMult(geo->veps, geo->vscratch[1], geo->vepspml); if(epsI != NULL){ // imaginary part of passive dielectric VecGetArray(geo->vMscratch[0], &scratch); for(i=ms; i<me; i++){ scratch[i-ms] = epsI[i-ms]; } VecRestoreArray(geo->vMscratch[0], &scratch); InterpolateVec(geo, geo->vMscratch[0], geo->vscratch[1]); VecPointwiseMult(geo->vscratch[1], geo->vscratch[1], geo->vepspml); TimesI(geo, geo->vscratch[1], geo->vscratch[2]); VecAXPY(geo->veps, 1.0, geo->vscratch[2]); } } if(manual_epspml){ char epsManualfile[PETSC_MAX_PATH_LEN]; PetscOptionsGetString(PETSC_NULL,PETSC_NULL,"-epsManualfile", epsManualfile, PETSC_MAX_PATH_LEN, NULL); FILE *fp = fopen(epsManualfile, "r"); ReadVectorC(fp, 2*Nxyzc(geo)+2, geo->veps); // 07/11/15: if manual_epspml, then directly read in the Nxyzcr+2 vector fclose(fp); } TimesI(geo, geo->veps, geo->vIeps); // vIeps for convenience only, make sure to update it later if eps ever changes! geo->D = 0.0; geo->wa = wa; geo->y = y; VecDuplicate(geo->veps, &geo->vf); VecDuplicate(geo->vMscratch[0], &geo->vfM); VecGetArray(geo->vfM, &scratch); for(i=ms; i<me;i++) scratch[i-ms] = fprof[i-ms]; VecRestoreArray(geo->vfM, &scratch); InterpolateVec(geo, geo->vfM, geo->vf); return geo; }