void main(int argc, char *argv[]){ int t; char fname1[100], fname2[100]; int m = sprintf(fname1,"phi"); int n = sprintf(fname2,"velocities"); MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&numtasks); MPI_Comm_rank(MPI_COMM_WORLD,&taskid); numworkers = numtasks - 1; allocate_memory_phasefields(MESHX); #ifdef FLUID allocate_memory_FluidVariables(MESHX,pmesh); #endif if(taskid == MASTER) { initialize_phasefields(); #ifdef FLUID initialize_velocities(MESHX); #endif mpi_distribute(MESHX); for (t = 0; t <= phi_timesteps; t++){ #ifdef FLUID gauss_siedel(); #endif if (t%save_phi == 0) { receivefrmworker(phi_old); receivefrmworker(u_old); receivefrmworker(v_old); write2file( t, MESHX, phi_old, fname1); write2file1( t, MESHX, u_old, v_old, fname2); } } }else { mpi_distribute(MESHX); for (t = 0; t <= phi_timesteps; t++){ mpiexchange(taskid, phi_old, MESHX); mpiexchange(taskid, mu_old, MESHX); boundary_mpi(taskid, phi_old, MESHX); boundary_mpi(taskid, mu_old, MESHX); laplacian(phi_old, lap_phi, MESHX); laplacian(mu_old, lap_mu, MESHX); #ifdef FLUID computeH(u_old,v_old,Hx,Hy); RHS_fn(Hx,Hy,rhs_fn,MESHX, pmesh); LHS_fn(MESHX, pmesh); boundary_pressure(taskid); gauss_siedel(); ns_solver(start, end, phi_old); update_velocities(MESHX); #endif solverloop(); phi_update(); if (t%save_phi == 0) { sendtomaster(taskid, phi_old); } } } }
void multiDS(int n, double *x, double cc, double ce, double lmin, double lstart, int maxiter) { int i, imin, replaced, iter = 0; double **xs, **xr, **xe, **xc, *fs, *fr, *fe, *fc, fsmin, frmin, femin, fcmin, ssize; FILE *fp; void initSimplex(int, double *, double **, double); void printSimplex(int, int, double **, double *); void findBest(int, double **, double *, int *, double *); void copySimplex(int, double **, double **, double *, double *); double simplexSize(int, double **); void vecAdd(int, double *, double *, double *, double); double dmin(int, double *); void mpi_assign(int); void mpi_distribute(int, double *); /* Initial size of simplex */ ssize = lstart; /* Check validity of input parameters */ if(cc <= 0.0 || cc >= 1.0) { printf("multiDS: contraction coefficient must be in (0,1)\n"); exit(0); } if(ce <= 1.0) { printf("multiDS: expandion coefficient must be > 1\n"); exit(0); } if(ssize < lmin) { printf("multiDS: starting simplex size is < minimum\n"); printf(" give lstart > lmin\n"); exit(0); } printf("Parameters for search:\n"); printf(" Contraction factor = %e\n", cc); printf(" Expansion factor = %e\n", ce); printf(" Starting simplex size = %e\n", ssize); printf(" Minimum simplex size = %e\n", lmin); printf(" Maximum number of iter = %d\n", maxiter); /* Allocate memory */ xs = (double **) calloc((n + 1), sizeof(double *)); xr = (double **) calloc((n + 1), sizeof(double *)); xe = (double **) calloc((n + 1), sizeof(double *)); xc = (double **) calloc((n + 1), sizeof(double *)); fs = (double *) calloc(n + 1, sizeof(double)); fr = (double *) calloc(n + 1, sizeof(double)); fe = (double *) calloc(n + 1, sizeof(double)); fc = (double *) calloc(n + 1, sizeof(double)); for(i = 0; i < n + 1; i++) { xs[i] = (double *) calloc(n, sizeof(double)); xr[i] = (double *) calloc(n, sizeof(double)); xe[i] = (double *) calloc(n, sizeof(double)); xc[i] = (double *) calloc(n, sizeof(double)); } /* Initialize the simplex */ initSimplex(n, x, xs, ssize); /* Assign evaluations to different proc */ mpi_assign(n); /* Calculate initial function values */ /* Zeroth vertex is starting vertex, cost = 1. No need to calculate again * since it is already done in multiDS_driver.c */ fs[0] = cost0; for(i = 1; i < n + 1; i++) { if(proc[i] == myproc) fs[i] = objFun(n, xs[i]); } /* Distribute cost functions */ mpi_distribute(n, fs); printf("Initial simplex and function values:\n"); printSimplex(0, n, xs, fs); /* Find best vertex and put in first position */ findBest(n, xs, fs, &imin, &fsmin); if(myproc == 0) fp = fopen("cost.dat", "w"); /* Main iteration loop */ while(ssize > lmin && iter < maxiter) { printf("Iteration = %d\n\n", iter + 1); replaced = 0; while(!replaced && ssize > lmin) { /* inner repeat loop */ /* rotation step */ printf(" Rotation:\n"); for(i = 1; i <= n; i++) { vecAdd(n, xs[0], xs[i], xr[i], 1.0); if(proc[i] == myproc) fr[i] = objFun(n, xr[i]); } mpi_distribute(n, fr); printSimplex(1, n, xr, fr); frmin = dmin(n, fr); replaced = (frmin < fs[0]) ? 1 : 0; if(replaced) { /* expansion step */ printf(" Expansion:\n"); for(i = 1; i <= n; i++) { vecAdd(n, xs[0], xs[i], xe[i], ce); if(proc[i] == myproc) fe[i] = objFun(n, xe[i]); } mpi_distribute(n, fe); printSimplex(1, n, xe, fe); femin = dmin(n, fe); if(femin < frmin) copySimplex(n, xe, xs, fe, fs); //accept expansion else copySimplex(n, xr, xs, fr, fs); //accept rotation } else { /* contraction step */ printf(" Contraction step:\n"); for(i = 1; i <= n; i++) { vecAdd(n, xs[0], xs[i], xc[i], -cc); if(proc[i] == myproc) fc[i] = objFun(n, xc[i]); } mpi_distribute(n, fc); printSimplex(1, n, xc, fc); fcmin = dmin(n, fc); replaced = (fcmin < fs[0]) ? 1 : 0; copySimplex(n, xc, xs, fc, fs); //accept contraction } /* Length of smallest edge in simplex */ ssize = simplexSize(n, xs); } /* End of inner repeat loop */ ++iter; /* Find best vertex and put in first position */ findBest(n, xs, fs, &imin, &fsmin); printf("\n"); printf("Minimum length of simplex = %12.4e\n", ssize); printf("Minimum function value = %12.4e\n", fs[0]); printf("-------------------------------------------------\n"); if(myproc == 0) { fprintf(fp, "%5d %20.10e %20.10e %5d\n", iter, fs[0], ssize, imin); fflush(fp); } } /* End of main iteration loop */ if(myproc == 0) fclose(fp); /* Copy best vertex for output */ for(i = 0; i < n; i++) x[i] = xs[0][i]; /* Best vertex found */ printf("Best vertex:\n"); for(i = 0; i < n; i++) printf("%e ", x[i]); printf("\n"); /* Free memory */ for(i = 0; i < n + 1; i++) { free(xs[i]); free(xr[i]); free(xe[i]); free(xc[i]); } free(xs); free(xr); free(xe); free(xc); free(fs); free(fr); free(fe); free(fc); }