void rt_set_numthreads(SceneHandle voidscene, int numthreads) { scenedef * scene = (scenedef *) voidscene; #ifdef THR if (numthreads > 0) { scene->numthreads = numthreads; } else { scene->numthreads = rt_thread_numprocessors(); } /* force set of # kernel threads */ rt_thread_setconcurrency(scene->numthreads); #else scene->numthreads = 1; #endif scene->scenecheck = 1; }
int calc_grid_energies_excl_mgrid(float* atoms, float* grideners, long int numplane, long int numcol, long int numpt, long int natoms, float gridspacing, unsigned char* excludepos, int maxnumprocs) { // cionize_params* params, cionize_molecule* molecule, cionize_grid* grid) { int i; enthrparms *parms; rt_thread_t * threads; #if defined(THR) int numprocs; int availprocs = rt_thread_numprocessors(); if (params->maxnumprocs <= availprocs) { numprocs = params->maxnumprocs; } else { numprocs = availprocs; } #else int numprocs = 1; #endif printf("calc_grid_energies_excl_mgrid()\n"); /* DH: setup and compute long-range */ MgridParam mg_prm; MgridSystem mg_sys; Mgrid mg; //MgridLattice *lattice; int j, k; int gridfactor; double h, h_1; int nspacings; double *eh; int ndim; int ii, jj, kk; int im, jm, km; int ilo, jlo, klo; double dx_h, dy_h, dz_h; double xphi[4], yphi[4], zphi[4]; double t, en, c; int koff, jkoff, index; rt_timerhandle timer; float totaltime; memset(&mg_prm, 0, sizeof(mg_prm)); memset(&mg_sys, 0, sizeof(mg_sys)); /* * set mgrid parameters * * make sure origin of mgrid's grid is at ionize's grid origin (0,0,0) * * length is (number of grid spacings) * (grid spacing), * where the number of spacings is one less than number of grid points */ mg_prm.length = (numpt-1) * gridspacing; mg_prm.center.x = 0.5 * mg_prm.length; mg_prm.center.y = 0.5 * mg_prm.length; mg_prm.center.z = 0.5 * mg_prm.length; /* make sure domain and grid are both cubic */ if (numpt != numcol || numcol != numplane) { printf("ERROR: grid must be cubic\n"); return -1; } /* * grid used by mgrid needs spacing h >= 2 * * determine grid factor: (2^gridfactor)*h_ionize = h_mgrid */ gridfactor = 0; //nspacings = numpt - 1; nspacings = numpt; /* add one more spacing so that interpolation loop below will work */ h = gridspacing; while (h < 2.0) { h *= 2; nspacings = ((nspacings & 1) ? nspacings/2 + 1 : nspacings/2); gridfactor++; } mg_prm.nspacings = nspacings; /* have to modify mgrid length */ mg_prm.length += h; mg_prm.center.x = 0.5 * mg_prm.length; mg_prm.center.y = 0.5 * mg_prm.length; mg_prm.center.z = 0.5 * mg_prm.length; h_1 = 1.0/h; mg_prm.cutoff = CUTOFF; mg_prm.boundary = MGRID_NONPERIODIC; /* choice of splitting must be consistent with short-range below */ #if defined(CUBIC_TAYLOR2) mg_prm.approx = MGRID_CUBIC; mg_prm.split = MGRID_TAYLOR2; #elif defined(QUINTIC1_TAYLOR3) mg_prm.approx = MGRID_QUINTIC1; mg_prm.split = MGRID_TAYLOR3; #elif defined(HEPTIC1_TAYLOR4) mg_prm.approx = MGRID_HEPTIC1; mg_prm.split = MGRID_TAYLOR4; /* #elif defined(HERMITE_TAYLOR3) mg_prm.approx = MGRID_HERMITE; mg_prm.split = MGRID_TAYLOR3; */ #endif mg_prm.natoms = natoms; printf("natom = %d\n", mg_prm.natoms); printf("mgrid center = %g %g %g\n", mg_prm.center.x, mg_prm.center.y, mg_prm.center.z); printf("mgrid length = %g\n", mg_prm.length); printf("mgrid nspacings = %d\n", mg_prm.nspacings); /* setup mgrid system */ mg_sys.f_elec = (MD_Dvec *) calloc(mg_prm.natoms, sizeof(MD_Dvec)); mg_sys.pos = (MD_Dvec *) calloc(mg_prm.natoms, sizeof(MD_Dvec)); mg_sys.charge = (double *) calloc(mg_prm.natoms, sizeof(double)); for (i = 0; i < mg_prm.natoms; i++) { mg_sys.pos[i].x = atoms[4*i ]; mg_sys.pos[i].y = atoms[4*i + 1]; mg_sys.pos[i].z = atoms[4*i + 2]; mg_sys.charge[i] = atoms[4*i + 3]; } /* setup mgrid solver and compute */ if (mgrid_param_config(&mg_prm)) { printf("ERROR: mgrid_param_config() failed\n"); return -1; } printf("spacing = %g\n", mg_prm.spacing); if (mgrid_init(&mg)) { printf("ERROR: mgrid_init() failed\n"); return -1; } if (mgrid_setup(&mg, &mg_sys, &mg_prm)) { printf("ERROR: mgrid_setup() failed\n"); return -1; } timer = rt_timer_create(); rt_timer_start(timer); if (mgrid_force(&mg, &mg_sys)) { printf("ERROR: mgrid_force() failed\n"); return -1; } /* DH: end setup and compute long-range */ printf(" using %d processors\n", numprocs); /* allocate array of threads */ threads = (rt_thread_t *) calloc(numprocs * sizeof(rt_thread_t), 1); /* allocate and initialize array of thread parameters */ parms = (enthrparms *) malloc(numprocs * sizeof(enthrparms)); for (i=0; i<numprocs; i++) { parms[i].threadid = i; parms[i].threadcount = numprocs; parms[i].atoms = atoms; parms[i].grideners = grideners; parms[i].numplane = numplane; parms[i].numcol = numcol; parms[i].numpt = numpt; parms[i].natoms = natoms; parms[i].gridspacing = gridspacing; parms[i].excludepos = excludepos; } #if defined(THR) /* spawn child threads to do the work */ for (i=0; i<numprocs; i++) { rt_thread_create(&threads[i], energythread, &parms[i]); } /* join the threads after work is done */ for (i=0; i<numprocs; i++) { rt_thread_join(threads[i], NULL); } #else /* single thread does all of the work */ energythread((void *) &parms[0]); #endif /* DH: tabulate and cleanup long-range */ /* interpolate from mgrid potential lattice */ eh = (double *)(mg.egrid[0].data); /* mgrid's long-range potential lattice */ ndim = mg.egrid[0].ni; /* number of points in each dimension of lattice */ for (kk = 0; kk < numplane; kk++) { for (jj = 0; jj < numcol; jj++) { for (ii = 0; ii < numpt; ii++) { /* distance between atom and corner measured in grid points */ dx_h = (ii*gridspacing) * h_1; dy_h = (jj*gridspacing) * h_1; dz_h = (kk*gridspacing) * h_1; /* find closest mgrid lattice point less than or equal to */ im = ii >> gridfactor; jm = jj >> gridfactor; km = kk >> gridfactor; #if defined(CUBIC_TAYLOR2) ilo = im-1; jlo = jm-1; klo = km-1; /* find t for x dimension and compute xphi */ t = dx_h - ilo; xphi[0] = 0.5 * (1 - t) * (2 - t) * (2 - t); t--; xphi[1] = (1 - t) * (1 + t - 1.5 * t * t); t--; xphi[2] = (1 + t) * (1 - t - 1.5 * t * t); t--; xphi[3] = 0.5 * (1 + t) * (2 + t) * (2 + t); /* find t for y dimension and compute yphi */ t = dy_h - jlo; yphi[0] = 0.5 * (1 - t) * (2 - t) * (2 - t); t--; yphi[1] = (1 - t) * (1 + t - 1.5 * t * t); t--; yphi[2] = (1 + t) * (1 - t - 1.5 * t * t); t--; yphi[3] = 0.5 * (1 + t) * (2 + t) * (2 + t); /* find t for z dimension and compute zphi */ t = dz_h - klo; zphi[0] = 0.5 * (1 - t) * (2 - t) * (2 - t); t--; zphi[1] = (1 - t) * (1 + t - 1.5 * t * t); t--; zphi[2] = (1 + t) * (1 - t - 1.5 * t * t); t--; zphi[3] = 0.5 * (1 + t) * (2 + t) * (2 + t); /* determine 64=4*4*4 eh grid stencil contribution to potential */ en = 0; for (k = 0; k < 4; k++) { koff = (k + klo) * ndim; for (j = 0; j < 4; j++) { jkoff = (koff + (j + jlo)) * ndim; c = yphi[j] * zphi[k]; for (i = 0; i < 4; i++) { index = jkoff + (i + ilo); /* ASSERT(&eh[index] == mgrid_lattice_elem(&(mg.egrid[0]), i+ilo, j+jlo, k+klo)); */ if (&eh[index] != mgrid_lattice_elem(&(mg.egrid[0]), i+ilo, j+jlo, k+klo)) { printf("ndim=%d index=%d i+ilo=%d j+jlo=%d k+klo=%d\n" "ia=%d ib=%d ni=%d\n" "ja=%d jb=%d nj=%d\n" "ka=%d kb=%d nk=%d\n", ndim, index, i+ilo, j+jlo, k+klo, mg.egrid[0].ia, mg.egrid[0].ib, mg.egrid[0].ni, mg.egrid[0].ja, mg.egrid[0].jb, mg.egrid[0].nj, mg.egrid[0].ka, mg.egrid[0].kb, mg.egrid[0].nk ); abort(); } en += eh[index] * xphi[i] * c; } } } /* end CUBIC */ #endif //ENERGY(grid->eners[k*numcol*numpt + j*numpt + i]); grideners[kk*numcol*numpt + jj*numpt + ii] += (float)en; // (float) *((double *)mgrid_lattice_elem(lattice, i, j, k)); //ENERGY((float) *((double *)mgrid_lattice_elem(lattice, i, j, k))); //ENERGY(grid->eners[k*numcol*numpt + j*numpt + i]*560.47254); } } } totaltime = rt_timer_timenow(timer); printf("total time for mgrid: %.1f\n", totaltime); rt_timer_destroy(timer); /* cleanup mgrid */ mgrid_done(&mg); free(mg_sys.f_elec); free(mg_sys.pos); free(mg_sys.charge); /* DH: tabulate and cleanup long-range */ /* free thread parms */ free(parms); free(threads); return 0; }