bondedtable_t make_bonded_table(FILE *fplog,char *fn,int angle) { t_tabledata td; double start; int i; bondedtable_t tab; if (angle < 2) start = 0; else start = -180.0; read_tables(fplog,fn,1,angle,&td); if (angle > 0) { /* Convert the table from degrees to radians */ for(i=0; i<td.nx; i++) { td.x[i] *= DEG2RAD; td.f[i] *= RAD2DEG; } td.tabscale *= RAD2DEG; } tab.n = td.nx; tab.scale = td.tabscale; snew(tab.tab,tab.n*4); copy2table(tab.n,0,4,td.x,td.v,td.f,tab.tab); done_tabledata(&td); return tab; }
t_forcetable make_tables(FILE *out,const output_env_t oenv, const t_forcerec *fr, gmx_bool bVerbose,const char *fn, real rtab,int flags) { const char *fns[3] = { "ctab.xvg", "dtab.xvg", "rtab.xvg" }; const char *fns14[3] = { "ctab14.xvg", "dtab14.xvg", "rtab14.xvg" }; FILE *fp; t_tabledata *td; gmx_bool b14only,bReadTab,bGenTab; real x0,y0,yp; int i,j,k,nx,nx0,tabsel[etiNR]; t_forcetable table; b14only = (flags & GMX_MAKETABLES_14ONLY); if (flags & GMX_MAKETABLES_FORCEUSER) { tabsel[etiCOUL] = etabUSER; tabsel[etiLJ6] = etabUSER; tabsel[etiLJ12] = etabUSER; } else { set_table_type(tabsel,fr,b14only); } snew(td,etiNR); table.r = rtab; table.scale = 0; table.n = 0; table.scale_exp = 0; nx0 = 10; nx = 0; /* Check whether we have to read or generate */ bReadTab = FALSE; bGenTab = FALSE; for(i=0; (i<etiNR); i++) { if (ETAB_USER(tabsel[i])) bReadTab = TRUE; if (tabsel[i] != etabUSER) bGenTab = TRUE; } if (bReadTab) { read_tables(out,fn,etiNR,0,td); if (rtab == 0 || (flags & GMX_MAKETABLES_14ONLY)) { rtab = td[0].x[td[0].nx-1]; table.n = td[0].nx; nx = table.n; } else { if (td[0].x[td[0].nx-1] < rtab) gmx_fatal(FARGS,"Tables in file %s not long enough for cut-off:\n" "\tshould be at least %f nm\n",fn,rtab); nx = table.n = (int)(rtab*td[0].tabscale + 0.5); } table.scale = td[0].tabscale; nx0 = td[0].nx0; } if (bGenTab) { if (!bReadTab) { #ifdef GMX_DOUBLE table.scale = 2000.0; #else table.scale = 500.0; #endif nx = table.n = rtab*table.scale; } } if (fr->bBHAM) { if(fr->bham_b_max!=0) table.scale_exp = table.scale/fr->bham_b_max; else table.scale_exp = table.scale; } /* Each table type (e.g. coul,lj6,lj12) requires four * numbers per nx+1 data points. For performance reasons we want * the table data to be aligned to 16-byte. */ snew_aligned(table.tab, 12*(nx+1)*sizeof(real),16); for(k=0; (k<etiNR); k++) { if (tabsel[k] != etabUSER) { init_table(out,nx,nx0, (tabsel[k] == etabEXPMIN) ? table.scale_exp : table.scale, &(td[k]),!bReadTab); fill_table(&(td[k]),tabsel[k],fr); if (out) fprintf(out,"%s table with %d data points for %s%s.\n" "Tabscale = %g points/nm\n", ETAB_USER(tabsel[k]) ? "Modified" : "Generated", td[k].nx,b14only?"1-4 ":"",tprops[tabsel[k]].name, td[k].tabscale); } copy2table(table.n,k*4,12,td[k].x,td[k].v,td[k].f,table.tab); if (bDebugMode() && bVerbose) { if (b14only) fp=xvgropen(fns14[k],fns14[k],"r","V",oenv); else fp=xvgropen(fns[k],fns[k],"r","V",oenv); /* plot the output 5 times denser than the table data */ for(i=5*((nx0+1)/2); i<5*table.n; i++) { x0 = i*table.r/(5*(table.n-1)); evaluate_table(table.tab,4*k,12,table.scale,x0,&y0,&yp); fprintf(fp,"%15.10e %15.10e %15.10e\n",x0,y0,yp); } gmx_fio_fclose(fp); } done_tabledata(&(td[k])); } sfree(td); return table; }
t_forcetable make_tables(FILE *out,const output_env_t oenv, const t_forcerec *fr, gmx_bool bVerbose,const char *fn, real rtab,int flags) { const char *fns[3] = { "ctab.xvg", "dtab.xvg", "rtab.xvg" }; const char *fns14[3] = { "ctab14.xvg", "dtab14.xvg", "rtab14.xvg" }; FILE *fp; t_tabledata *td; gmx_bool b14only,bReadTab,bGenTab; real x0,y0,yp; int i,j,k,nx,nx0,tabsel[etiNR]; real scalefactor; t_forcetable table; b14only = (flags & GMX_MAKETABLES_14ONLY); if (flags & GMX_MAKETABLES_FORCEUSER) { tabsel[etiCOUL] = etabUSER; tabsel[etiLJ6] = etabUSER; tabsel[etiLJ12] = etabUSER; } else { set_table_type(tabsel,fr,b14only); } snew(td,etiNR); table.r = rtab; table.scale = 0; table.n = 0; table.scale_exp = 0; nx0 = 10; nx = 0; table.interaction = GMX_TABLE_INTERACTION_ELEC_VDWREP_VDWDISP; table.format = GMX_TABLE_FORMAT_CUBICSPLINE_YFGH; table.formatsize = 4; table.ninteractions = 3; table.stride = table.formatsize*table.ninteractions; /* Check whether we have to read or generate */ bReadTab = FALSE; bGenTab = FALSE; for(i=0; (i<etiNR); i++) { if (ETAB_USER(tabsel[i])) bReadTab = TRUE; if (tabsel[i] != etabUSER) bGenTab = TRUE; } if (bReadTab) { read_tables(out,fn,etiNR,0,td); if (rtab == 0 || (flags & GMX_MAKETABLES_14ONLY)) { rtab = td[0].x[td[0].nx-1]; table.n = td[0].nx; nx = table.n; } else { if (td[0].x[td[0].nx-1] < rtab) gmx_fatal(FARGS,"Tables in file %s not long enough for cut-off:\n" "\tshould be at least %f nm\n",fn,rtab); nx = table.n = (int)(rtab*td[0].tabscale + 0.5); } table.scale = td[0].tabscale; nx0 = td[0].nx0; } if (bGenTab) { if (!bReadTab) { #ifdef GMX_DOUBLE table.scale = 2000.0; #else table.scale = 500.0; #endif nx = table.n = rtab*table.scale; } } if (fr->bBHAM) { if(fr->bham_b_max!=0) table.scale_exp = table.scale/fr->bham_b_max; else table.scale_exp = table.scale; } /* Each table type (e.g. coul,lj6,lj12) requires four * numbers per nx+1 data points. For performance reasons we want * the table data to be aligned to 16-byte. */ snew_aligned(table.data, 12*(nx+1)*sizeof(real),16); for(k=0; (k<etiNR); k++) { if (tabsel[k] != etabUSER) { init_table(out,nx,nx0, (tabsel[k] == etabEXPMIN) ? table.scale_exp : table.scale, &(td[k]),!bReadTab); fill_table(&(td[k]),tabsel[k],fr); if (out) fprintf(out,"%s table with %d data points for %s%s.\n" "Tabscale = %g points/nm\n", ETAB_USER(tabsel[k]) ? "Modified" : "Generated", td[k].nx,b14only?"1-4 ":"",tprops[tabsel[k]].name, td[k].tabscale); } /* Set scalefactor for c6/c12 tables. This is because we save flops in the non-table kernels * by including the derivative constants (6.0 or 12.0) in the parameters, since * we no longer calculate force in most steps. This means the c6/c12 parameters * have been scaled up, so we need to scale down the table interactions too. * It comes here since we need to scale user tables too. */ if(k==etiLJ6) { scalefactor = 1.0/6.0; } else if(k==etiLJ12 && tabsel[k]!=etabEXPMIN) { scalefactor = 1.0/12.0; } else { scalefactor = 1.0; } copy2table(table.n,k*4,12,td[k].x,td[k].v,td[k].f,scalefactor,table.data); if (bDebugMode() && bVerbose) { if (b14only) fp=xvgropen(fns14[k],fns14[k],"r","V",oenv); else fp=xvgropen(fns[k],fns[k],"r","V",oenv); /* plot the output 5 times denser than the table data */ for(i=5*((nx0+1)/2); i<5*table.n; i++) { x0 = i*table.r/(5*(table.n-1)); evaluate_table(table.data,4*k,12,table.scale,x0,&y0,&yp); fprintf(fp,"%15.10e %15.10e %15.10e\n",x0,y0,yp); } gmx_fio_fclose(fp); } done_tabledata(&(td[k])); } sfree(td); return table; }
t_forcetable make_atf_table(FILE *out,const output_env_t oenv, const t_forcerec *fr, const char *fn, matrix box) { const char *fns[3] = { "tf_tab.xvg", "atfdtab.xvg", "atfrtab.xvg" }; FILE *fp; t_tabledata *td; real x0,y0,yp,rtab; int i,nx,nx0; void * p_tmp; real rx, ry, rz, box_r; t_forcetable table; /* Set the table dimensions for ATF, not really necessary to * use etiNR (since we only have one table, but ...) */ snew(td,1); if (fr->adress_type == eAdressSphere){ /* take half box diagonal direction as tab range */ rx = 0.5*box[0][0]+0.5*box[1][0]+0.5*box[2][0]; ry = 0.5*box[0][1]+0.5*box[1][1]+0.5*box[2][1]; rz = 0.5*box[0][2]+0.5*box[1][2]+0.5*box[2][2]; box_r = sqrt(rx*rx+ry*ry+rz*rz); }else{ /* xsplit: take half box x direction as tab range */ box_r = box[0][0]/2; } table.r = box_r; table.scale = 0; table.n = 0; table.scale_exp = 0; nx0 = 10; nx = 0; read_tables(out,fn,1,0,td); rtab = td[0].x[td[0].nx-1]; if (fr->adress_type == eAdressXSplit && (rtab < box[0][0]/2)){ gmx_fatal(FARGS,"AdResS full box therm force table in file %s extends to %f:\n" "\tshould extend to at least half the length of the box in x-direction" "%f\n",fn,rtab, box[0][0]/2); } if (rtab < box_r){ gmx_fatal(FARGS,"AdResS full box therm force table in file %s extends to %f:\n" "\tshould extend to at least for spherical adress" "%f (=distance from center to furthermost point in box \n",fn,rtab, box_r); } table.n = td[0].nx; nx = table.n; table.scale = td[0].tabscale; nx0 = td[0].nx0; /* Each table type (e.g. coul,lj6,lj12) requires four * numbers per datapoint. For performance reasons we want * the table data to be aligned to 16-byte. This is accomplished * by allocating 16 bytes extra to a temporary pointer, and then * calculating an aligned pointer. This new pointer must not be * used in a free() call, but thankfully we're sloppy enough not * to do this :-) */ /* 4 fp entries per table point, nx+1 points, and 16 bytes extra to align it. */ p_tmp = malloc(4*(nx+1)*sizeof(real)+16); /* align it - size_t has the same same as a pointer */ table.tab = (real *) (((size_t) p_tmp + 16) & (~((size_t) 15))); copy2table(table.n,0,4,td[0].x,td[0].v,td[0].f,table.tab); if(bDebugMode()) { fp=xvgropen(fns[0],fns[0],"r","V",oenv); /* plot the output 5 times denser than the table data */ /* for(i=5*nx0;i<5*table.n;i++) */ for(i=5*((nx0+1)/2); i<5*table.n; i++) { /* x0=i*table.r/(5*table.n); */ x0 = i*table.r/(5*(table.n-1)); evaluate_table(table.tab,0,4,table.scale,x0,&y0,&yp); fprintf(fp,"%15.10e %15.10e %15.10e\n",x0,y0,yp); } ffclose(fp); } done_tabledata(&(td[0])); sfree(td); return table; }
void make_tables(FILE *out,t_forcerec *fr,bool bVerbose,char *fn) { static char *fns[3] = { "ctab.xvg", "dtab.xvg", "rtab.xvg" }; FILE *fp; t_tabledata *td; bool bReadTab,bGenTab; real x0,y0,yp,rtab; int i,j,k,nx,nx0,tabsel[etiNR]; set_table_type(tabsel,fr); snew(td,etiNR); fr->tabscale = 0; rtab = fr->rtab; nx0 = 10; nx = 0; /* Check whether we have to read or generate */ bReadTab = FALSE; bGenTab = FALSE; for(i=0; (i<etiNR); i++) { if (tabsel[i] == etabUSER) bReadTab = TRUE; else bGenTab = TRUE; } if (bReadTab) { read_tables(out,fn,td); fr->tabscale = td[0].tabscale; fr->rtab = td[0].x[td[0].nx-1]; nx0 = td[0].nx0; nx = fr->ntab = fr->rtab*fr->tabscale; if (fr->rtab < rtab) fatal_error(0,"Tables in file %s not long enough for cut-off:\n" "\tshould be at least %f nm\n",fn,rtab); } if (bGenTab) { if (!bReadTab) { #ifdef DOUBLE fr->tabscale = 2000.0; #else fr->tabscale = 500.0; #endif nx = fr->ntab = fr->rtab*fr->tabscale; } } snew(fr->coulvdwtab,12*(nx+1)+1); for(k=0; (k<etiNR); k++) { if (tabsel[k] != etabUSER) { init_table(out,nx,nx0,tabsel[k], (tabsel[k] == etabEXPMIN) ? fr->tabscale_exp : fr->tabscale, &(td[k]),!bReadTab); fill_table(&(td[k]),tabsel[k],fr); if (out) fprintf(out,"Generated table with %d data points for %s.\n" "Tabscale = %g points/nm\n", td[k].nx,tabnm[tabsel[k]],td[k].tabscale); } copy2table(td[k].nx,k*4,12,td[k].x,td[k].v,td[k].v2,fr->coulvdwtab,-1); if (bDebugMode() && bVerbose) { fp=xvgropen(fns[k],fns[k],"r","V"); for(i=td[k].nx0+1; (i<td[k].nx-1); i++) { for(j=0; (j<4); j++) { x0=td[k].x[i]+0.25*j*(td[k].x[i+1]-td[k].x[i]); splint(td[k].x,td[k].v,td[k].v2,nx-3,x0,&y0,&yp); if(fp) fprintf(fp,"%15.10e %15.10e %15.10e\n",x0,y0,yp); } } ffclose(fp); } done_tabledata(&(td[k])); } sfree(td); }