t_forcetable make_gb_table(FILE *out,const output_env_t oenv, const t_forcerec *fr, const char *fn, real rtab) { const char *fns[3] = { "gbctab.xvg", "gbdtab.xvg", "gbrtab.xvg" }; const char *fns14[3] = { "gbctab14.xvg", "gbdtab14.xvg", "gbrtab14.xvg" }; FILE *fp; t_tabledata *td; gmx_bool bReadTab,bGenTab; real x0,y0,yp; int i,j,k,nx,nx0,tabsel[etiNR]; void * p_tmp; double r,r2,Vtab,Ftab,expterm; t_forcetable table; double abs_error_r, abs_error_r2; double rel_error_r, rel_error_r2; double rel_error_r_old=0, rel_error_r2_old=0; double x0_r_error, x0_r2_error; /* Only set a Coulomb table for GB */ /* tabsel[0]=etabGB; tabsel[1]=-1; tabsel[2]=-1; */ /* Set the table dimensions for GB, not really necessary to * use etiNR (since we only have one table, but ...) */ snew(td,1); table.r = fr->gbtabr; table.scale = fr->gbtabscale; table.scale_exp = 0; table.n = table.scale*table.r; nx0 = 0; nx = table.scale*table.r; /* Check whether we have to read or generate * We will always generate a table, so remove the read code * (Compare with original make_table function */ bReadTab = FALSE; bGenTab = TRUE; /* 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))); init_table(out,nx,nx0,table.scale,&(td[0]),!bReadTab); /* Local implementation so we don't have to use the etabGB * enum above, which will cause problems later when * making the other tables (right now even though we are using * GB, the normal Coulomb tables will be created, but this * will cause a problem since fr->eeltype==etabGB which will not * be defined in fill_table and set_table_type */ for(i=nx0;i<nx;i++) { Vtab = 0.0; Ftab = 0.0; r = td->x[i]; r2 = r*r; expterm = exp(-0.25*r2); Vtab = 1/sqrt(r2+expterm); Ftab = (r-0.25*r*expterm)/((r2+expterm)*sqrt(r2+expterm)); /* Convert to single precision when we store to mem */ td->v[i] = Vtab; td->f[i] = Ftab; } 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=nx0;i<table.n;i++) { /* x0=i*table.r/(5*table.n); */ x0=i*table.r/table.n; evaluate_table(table.tab,0,4,table.scale,x0,&y0,&yp); fprintf(fp,"%15.10e %15.10e %15.10e\n",x0,y0,yp); } gmx_fio_fclose(fp); } /* for(i=100*nx0;i<99.81*table.n;i++) { r = i*table.r/(100*table.n); r2 = r*r; expterm = exp(-0.25*r2); Vtab = 1/sqrt(r2+expterm); Ftab = (r-0.25*r*expterm)/((r2+expterm)*sqrt(r2+expterm)); evaluate_table(table.tab,0,4,table.scale,r,&y0,&yp); printf("gb: i=%d, x0=%g, y0=%15.15f, Vtab=%15.15f, yp=%15.15f, Ftab=%15.15f\n",i,r, y0, Vtab, yp, Ftab); abs_error_r=fabs(y0-Vtab); abs_error_r2=fabs(yp-(-1)*Ftab); rel_error_r=abs_error_r/y0; rel_error_r2=fabs(abs_error_r2/yp); if(rel_error_r>rel_error_r_old) { rel_error_r_old=rel_error_r; x0_r_error=x0; } if(rel_error_r2>rel_error_r2_old) { rel_error_r2_old=rel_error_r2; x0_r2_error=x0; } } printf("gb: MAX REL ERROR IN R=%15.15f, MAX REL ERROR IN R2=%15.15f\n",rel_error_r_old, rel_error_r2_old); printf("gb: XO_R=%g, X0_R2=%g\n",x0_r_error, x0_r2_error); exit(1); */ done_tabledata(&(td[0])); 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; }
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; }
tree evaluate_impl (tree t) { //cout << "Really evaluate " << t << LF; switch (L(t)) { /* Typesetting primitives with side effects */ case DATOMS: return evaluate_formatting (t, ATOM_DECORATIONS); case DLINES: return evaluate_formatting (t, LINE_DECORATIONS); case DPAGES: return evaluate_formatting (t, PAGE_DECORATIONS); case TFORMAT: return evaluate_formatting (t, CELL_FORMAT); case TABLE: return evaluate_table (t); /* Primitives for macro expansion */ case ASSIGN: return evaluate_assign (t); case WITH: return evaluate_with (t); case PROVIDES: return evaluate_provides (t); case VALUE: return evaluate_value (t); case QUOTE_VALUE: return evaluate_quote_value (t); case MACRO: return copy (t); case DRD_PROPS: return evaluate_drd_props (t); #ifdef CLASSICAL_MACRO_EXPANSION case ARG: return evaluate_arg (t); case QUOTE_ARG: return evaluate_quote_arg (t); #endif case COMPOUND: return evaluate_compound (t); case XMACRO: return copy (t); case GET_LABEL: return evaluate_get_label (t); case GET_ARITY: return evaluate_get_arity (t); /* Primitives for quoting and evaluation */ case MAP_ARGS: return evaluate_rewrite (t); case EVAL_ARGS: return evaluate_eval_args (t); case MARK: return tree (MARK, copy (t[0]), evaluate (t[1])); case EXPAND_AS: return evaluate (t[1]); case EVAL: return evaluate (evaluate (t[0])); case QUOTE: return t[0]; case QUASI: return evaluate (evaluate_quasiquote (t[0])); case QUASIQUOTE: return evaluate_quasiquote (t[0]); case UNQUOTE: case VAR_UNQUOTE: return evaluate (t[0]); case COPY: return copy (evaluate (t[0])); /* Control structures */ case IF: case VAR_IF: return evaluate_if (t); case CASE: return evaluate_case (t); case WHILE: return evaluate_while (t); case FOR_EACH: return evaluate_for_each (t); case EXTERN: return evaluate_rewrite (t); case VAR_INCLUDE: return evaluate_include (t); case WITH_PACKAGE: return evaluate_rewrite (t); case USE_PACKAGE: return evaluate_use_package (t); case USE_MODULE: return evaluate_use_module (t); /* Computational markup */ case OR: return evaluate_or (t); case XOR: return evaluate_xor (t); case AND: return evaluate_and (t); case NOT: return evaluate_not (t); case PLUS: case MINUS: return evaluate_plus_minus (t); case TIMES: case OVER: return evaluate_times_over (t); case DIV: return evaluate_divide (t); case MOD: return evaluate_modulo (t); case MATH_SQRT: return evaluate_math_sqrt (t); case EXP: return evaluate_exp (t); case LOG: return evaluate_log (t); case POW: return evaluate_pow (t); case COS: return evaluate_cos (t); case SIN: return evaluate_sin (t); case TAN: return evaluate_tan (t); case MERGE: return evaluate_merge (t); case LENGTH: return evaluate_length (t); case RANGE: return evaluate_range (t); case NUMBER: return evaluate_number (t); case _DATE: return evaluate_date (t); case TRANSLATE: return evaluate_translate (t); case CHANGE_CASE: return evaluate_change_case (t); case FIND_FILE: return evaluate_find_file (t); case IS_TUPLE: return evaluate_is_tuple (t); case LOOK_UP: return evaluate_lookup (t); case EQUAL: return evaluate_equal (t); case UNEQUAL: return evaluate_unequal (t); case LESS: return evaluate_less (t); case LESSEQ: return evaluate_lesseq (t); case GREATER: return evaluate_greater (t); case GREATEREQ: return evaluate_greatereq (t); case BLEND: return evaluate_blend (t); /* Length units */ case CM_LENGTH: return evaluate_cm_length (); case MM_LENGTH: return evaluate_mm_length (); case IN_LENGTH: return evaluate_in_length (); case PT_LENGTH: return evaluate_pt_length (); case BP_LENGTH: return evaluate_bp_length (); case DD_LENGTH: return evaluate_dd_length (); case PC_LENGTH: return evaluate_pc_length (); case CC_LENGTH: return evaluate_cc_length (); case FS_LENGTH: return evaluate_fs_length (); case FBS_LENGTH: return evaluate_fbs_length (); case EM_LENGTH: return evaluate_em_length (); case LN_LENGTH: return evaluate_ln_length (); case SEP_LENGTH: return evaluate_sep_length (); case YFRAC_LENGTH: return evaluate_yfrac_length (); case EX_LENGTH: return evaluate_ex_length (); case FN_LENGTH: return evaluate_fn_length (); case FNS_LENGTH: return evaluate_fns_length (); case BLS_LENGTH: return evaluate_bls_length (); case FNBOT_LENGTH: return evaluate_fnbot_length (); case FNTOP_LENGTH: return evaluate_fntop_length (); case SPC_LENGTH: return evaluate_spc_length (); case XSPC_LENGTH: return evaluate_xspc_length (); case PAR_LENGTH: return evaluate_par_length (); case PAG_LENGTH: return evaluate_pag_length (); case GW_LENGTH: return evaluate_gw_length (); case GH_LENGTH: return evaluate_gh_length (); case GU_LENGTH: return evaluate_gu_length (); case TMPT_LENGTH: return evaluate_tmpt_length (); case PX_LENGTH: return evaluate_px_length (); case MSEC_LENGTH: return evaluate_msec_length (); case SEC_LENGTH: return evaluate_sec_length (); case MIN_LENGTH: return evaluate_min_length (); case HR_LENGTH: return evaluate_hr_length (); /* Primitives for stylesheet editing */ case STYLE_WITH: case VAR_STYLE_WITH: return evaluate (t[N(t)-1]); case STYLE_ONLY: case VAR_STYLE_ONLY: case ACTIVE: case VAR_ACTIVE: case INACTIVE: case VAR_INACTIVE: return evaluate_compound (t); case REWRITE_INACTIVE: return evaluate_rewrite (t); /* Linking primitives */ case HARD_ID: return evaluate_hard_id (t[0]); case SCRIPT: return evaluate_script (t); case HLINK: case ACTION: return evaluate_compound (t); case SET_BINDING: return evaluate_set_binding (t); case GET_BINDING: return evaluate_get_binding (t); /* Graphical primitives */ case PATTERN: return evaluate_pattern (t); case _POINT: return evaluate_point (t); /* case BOX_INFO: return evaluate_box_info (t); case FRAME_DIRECT: return evaluate_frame_direct (t); case FRAME_INVERSE: return evaluate_frame_inverse (t); */ /* User extensions */ default: if (L(t) < START_EXTENSIONS) { int i, n= N(t); tree r (t, n); for (i=0; i<n; i++) r[i]= evaluate (t[i]); transfer_ip (t, r); return r; } else { tree r= evaluate_compound (t); return r; } } }