/** * Simulates the line-of-sight calculation on GPU.- * */ static int DoProfile_gpu (double **Obst_high, double **Obst_dist, double **Offset, double ResDist, double **Raster, double xBS, double yBS, double ZoTransBS, int xN, int yN, double scale, double radius) { #ifdef _PERFORMANCE_METRICS_ measure_time ("Simulating Line-of-sight on GPU"); #endif double AZI; int ix, iy; double dx, dy; // // LOS and obstacle height calculation is executed only once, // because its results are constant throughout the optimization // /* Offset ini for (ix = 0; ix < xN; ix++) { for (iy = 0; iy < yN; iy++) { Offset[ix][iy]=999; } }*/ // Kvadrant I for (ix = 0; ix < xN; ix++) { //Patrik AZI = atan((ix - xBS) / yBS); AZI = atan((ix - floor(xBS)) / floor(yBS)); if (cos(AZI) > sin(AZI)) { //Patrik dx = sin(AZI) / cos(AZI); //Patrik dy = -cos(AZI) / cos(AZI); dx = (ix - floor(xBS)) / floor(yBS); // tan(AZI) dy = -1; } else { //Patrik dx = sin(AZI) / sin(AZI); //Patrik dy = -cos(AZI) / sin(AZI); dx = 1; dy = -floor(yBS)/(ix - floor(xBS)); // ctan(AZI) } calc_profile (Obst_high, Obst_dist, Raster, Offset, dx, dy, xBS, yBS, ZoTransBS, xN, yN, scale, radius); #ifdef _DEBUG_INFO_ printf ("DoProfile -> 1st quadrant: %d\n", ix); #endif } /* Kvadrant III for (ix = 0; ix < xN; ix++) { //Patrik AZI = atan((ix - xBS) / (yN - yBS)); AZI = atan((ix - floor(xBS)) / (yN - floor(yBS))); if (cos(AZI) > sin(AZI)) { //Patrik dx = sin(AZI) / cos(AZI); //Patrik dy = cos(AZI) / cos(AZI); dx = (ix - floor(xBS)) / (yN - floor(yBS)); // tan(AZI) dy = 1; } else { //Patrik dx = sin(AZI) / sin(AZI); //Patrik dy = cos(AZI) / sin(AZI); dx = 1; dy = (yN - floor(yBS)) / (ix - floor(xBS)); // ctan(AZI) } calc_profile (Obst_high, Obst_dist, Raster, Offset, dx, dy, xBS, yBS, ZoTransBS, xN, yN, scale, radius); #ifdef _DEBUG_INFO_ printf ("DoProfile -> 3rd quadrant: %d\n", ix); #endif } // Kvadrant II for (iy = 0; iy < yN; iy++) { //Patrik AZI = atan((iy - yBS) / (xN - xBS)); AZI = atan((iy - floor(yBS)) / (xN - floor(xBS))); if (cos(AZI) > sin(AZI)) { //Patrik dx = cos(AZI) / cos(AZI); //Patrik dy = sin(AZI) / cos(AZI); dx = 1; dy = (iy - floor(yBS)) / (xN - floor(xBS)); // tan(AZI) } else { //Patrik dx = cos(AZI) / sin(AZI); //Patrik dy = sin(AZI) / sin(AZI); dx = (xN - floor(xBS)) / (iy - floor(yBS)); // ctan(AZI) dy = 1; } calc_profile (Obst_high, Obst_dist, Raster, Offset, dx, dy, xBS, yBS, ZoTransBS, xN, yN, scale, radius); #ifdef _DEBUG_INFO_ printf ("DoProfile -> 2nd quadrant: %d\n", ix); #endif } // Kvadrant IV for (iy = 0; iy < yN; iy++) { //Patrik AZI = atan((iy - yBS) / xBS); AZI = atan((iy - floor(yBS)) / floor(xBS)); if (cos(AZI) > sin(AZI)) { //Patrik dx = -cos(AZI) / cos(AZI); //Patrik dy = sin(AZI) / cos(AZI); dx = -1; dy = (iy - floor(yBS)) / floor(xBS); // tan(AZI) } else { //Patrik dx = -cos(AZI) / sin(AZI); //Patrik dy = sin(AZI) / sin(AZI); dx = -floor(xBS) / (iy - floor(yBS)); // ctan(AZI) dy = 1; } calc_profile (Obst_high, Obst_dist, Raster, Offset, dx, dy, xBS, yBS, ZoTransBS, xN, yN, scale, radius); #ifdef _DEBUG_INFO_ printf ("DoProfile -> 4th quadrant: %d\n", ix); #endif }*/ #ifdef _PERFORMANCE_METRICS_ measure_time (NULL); #endif return 0; }
/* volume of a domain */ real volume (struct potpars *pp, struct pdb_ATOM model[], struct domain *dom, struct pprofile *prf) { real vol, Rmax, zmin, zmax; real min; /* global (hopefully) minimum in the total potential */ int i,first,last; /* take all atoms of this and neighboring domains: "Take them out. All of them!" (Senator Palpartine aka Darth Sidious) */ first = (dom->prev) ? dom->prev->first_site : dom->first_site; last = (dom->next) ? dom->next->last_site : dom->last_site; pp->ncenters=last-first + 1; mesg(SUB1,"volume(): Using %d atoms (%d -> %d), centered on domain '%s'.", pp->ncenters,first,last,dom->description); Rmax = (prf->bSet) ? prf->Rmax : dom->rho1/10.0; zmin=(dom->z1 - dom->dz/2.0)/10.0; zmax=(dom->z2 + dom->dz/2.0)/10.0; /* setup the function to be integrated */ /* (1) find the minimum - requires a function in cartesian coordinates -> setup the centers in cartesian - use cartesian vlj() */ { Cartesian pos; pp->xyzcenters=grid2_alloc(pp->ncenters,3); for(i=0;i<pp->ncenters;i++) { pos = cyl2cart(model[i+first].cpos); pp->xyzcenters[i][XX]=pos.x/10.0; pp->xyzcenters[i][YY]=pos.y/10.0; pp->xyzcenters[i][ZZ]=pos.z/10.0; } init_vljcyl(pp); mesg(VERBOSE,"Potential: %s with ffgmx OW-CH4 interaction parameters at T=%g K", "Lennard-Jones 12-6 V_LJ(x,y,z)", pp->Temp); pp->min=find_min(vljvec,Rmax,zmin,zmax,NULL); mesg(VERBOSE,"Minimum: %f\n",pp->min); } /* (2) calculate the volume - this is better done in cylindrical coordinates --> setup again (and use cylindrical LJ) */ /* These cylindrical coordinates are buried in structures; I rather have them as simple arrays: AND Length has to be in nm (not Angstrom) because this is the length unit in the Lennard-Jones parameters (currently CH4-OW hardcoded) */ pp->centers=grid2_alloc(pp->ncenters,3); for(i=0;i<pp->ncenters;i++) { pp->centers[i][RAD]=model[i+first].cpos.rho/10.0; pp->centers[i][PHI]=model[i+first].cpos.phi; pp->centers[i][ZZZ]=model[i+first].cpos.z/10.0; } init_vljcyl(pp); /* now with the minimum found and with the LJ-centers in cylindrical coordinates! */ mesg(VERBOSE,"Potential: Shifted Lennard-Jones 12-6 V_LJ(r,phi,z) - %g kT " "with ffgmx OW-CH4 interaction parameters at T=%g K", pp->min, pp->Temp); init_gaussleg(pp->ngaussleg); mesg(VERBOSE,"Using %d-point Gauss-Legendre quadrature for the volume integrals.", pp->ngaussleg); if (prf->bPlot) plot_potential(vljcyl,Rmax,zmin,zmax,prf->nzplot); /* mesg(VERBOSE,"Potential: %s with ffgmx OW-CH4 interaction parameters", (prf->pot == vRljcyl) ? "WCA repulsive V_R,LJ(r)" : "Lennard-Jones 12-6 V_LJ(r)"); */ #ifdef TESTCASE { real vexact; /* test case: this should give the exact volume */ mesg(SUB1,"-------> Internal test of volume integration <-------"); vexact=PI*Rmax*Rmax*(zmax-zmin); mesg(SUB1,"VOLUME_TEST: R[nm] <%f> R_c[nm] <%f> L[nm] <%f> V=¶·R_c²·L[nm³] <%f>", dom->r1/10.0, Rmax, zmax-zmin, vexact); vol=cylint(cylconst, 0,Rmax, 0, 2*PI, zmin,zmax); mesg(SUB1,"VOLUME_TEST: f=1: Volume <%f> V_exact <%f>", vol,vexact); vol=cylint(cylcos, 0,Rmax, 0, 2*PI, zmin,zmax); vexact=0; mesg(SUB1,"VOLUME_TEST: f=cos(phi): Volume <%f> V_exact <%f>", vol,vexact); vol=cylint(cyl3, 0,Rmax, 0, 2*PI, 0,zmax-zmin); vexact=(1-exp(-Rmax))*PI*pow(zmax-zmin,3)/3.0; mesg(SUB1,"VOLUME_TEST: f=1/r exp(-r)*cos(phi)*cos(phi)*z: Volume <%f> V_exact <%f>", vol,vexact); vexact=1.0; /* PI*Rmax*Rmax*(zmax-zmin); */ vol = tdavg(Qvol,Zero, Rmax,zmin,zmax); mesg(SUB1,"VOLUME_TEST: <Qvol>, V(r)=0: Volume <%f> V_exact <%f>", vol,vexact); /* this analytical soln is alraedy specialised for FHG=6 */ vexact=(1.0-4.0*exp(-3.0))/(1-exp(-6.0*Rmax)*(1.0+6.0*Rmax)); vol = tdavg(Qvol,LinCheck, Rmax,zmin,zmax); mesg(SUB1,"VOLUME_TEST: <Qvol>, V(r)=6r: Volume <%f> V_exact <%f>", vol,vexact); /* correct one, f = 6, gives the same as above */ #define FHG 6.0 vexact= -(exp(FHG*(-0.5 + Rmax))* (-2.0 + 2.0*exp(FHG/2.) - FHG))/ (2.*(1.0 - exp(FHG*Rmax) + FHG*Rmax)); vol = tdavg(Qvol,LinCheck, Rmax,zmin,zmax); mesg(SUB1,"VOLUME_TEST: <Qvol>, V(r)=f/beta r nm^-1: Volume <%f> V_exact <%f>", vol,vexact); /* g(E) * exp(-bE) * f() f(r) = K1/2 r^2 (integral from Mathematica) */ vexact=2.0*PI*(zmax-zmin)* (K1*pow(Rmax,2) - (3.0*sqrt(2.0/PI)*sqrt(K1*pow(Rmax,2)))/ exp((K1*pow(Rmax,2))/2.) + (3.0 - K1*pow(Rmax,2))* erf(sqrt(K1*pow(Rmax,2))/sqrt(2)))/(2.*K1); vol = xV(harmonic,Rmax,zmin,zmax); mesg(SUB1,"VOLUME_TEST: xV: V(r)= k/2b r² nm^-1: Volume <%f> V_exact <%f>", vol,vexact); mesg(SUB1,"------> End of testcases <-------\n"); } #endif /* TESTCASE */ /* total volume */ /* simple & inefficient (two integrations): V = <Q> = Tr Qexp(-beta H) / Tr exp(-beta H) */ mesg(INPUT,"VOLUME_INPUT: R[nm] <%f> R_c[nm] <%f> L[nm] <%f> V=¶·R_c²·L[nm³] <%f>", dom->r1/10.0, Rmax, zmax-zmin, PI*Rmax*Rmax*(zmax-zmin)); mesg(INPUT,"VOLUME_PARAMETERS: Rmax[nm] <%f> z1 <%f> z2 <%f>",Rmax,zmin, zmax); /* accessible volume, Labbook II, p84 */ vol = xV(vljshiftcyl,Rmax,zmin,zmax); mesg(INPUT,"VOLUME_DATA: xV Volume[nm³] <%f> R*[nm] <%f>\n", vol,sqrt(vol/(PI*(zmax-zmin)))); /* normalised configurational volume, Labbok II, p79 (rubbish!) */ vol = Zsum(vljshiftcyl,Rmax,zmin,zmax); mesg(INPUT,"VOLUME_DATA: v1/Z Volume[nm³] <%f> R*[nm] <%f>\n", vol,sqrt(vol/(PI*(zmax-zmin)))); /* Thermodynamic average at fixed particle energy, Labbook II, p78 */ /* vol = tdavg(Qvol,prf->pp->u1, Rmax,zmin,zmax); */ /* mesg(INPUT,"VOLUME_DATA: <Qvol> Volume[nm³] <%f> R*[nm] <%f>\n", */ /* vol,sqrt(vol/(PI*(zmax-zmin)))); */ /* Pure configurational volume (unnormalised) */ /* vol = cylint(Z_V, 0,Rmax, 0,2*PI, zmin,zmax); */ /* mesg(INPUT,"VOLUME_DATA: v1 Volume[nm³] <%f> R*[nm] <%f>\n", */ /* vol,sqrt(vol/(PI*(zmax-zmin)))); */ if (prf->bSet) calc_profile(prf); free_gaussleg(); free(pp->centers); free(pp->xyzcenters); return vol; }