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_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; }
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); }