void fcs_update_pottab(void) { int i, j, k, col; real fcs_shift, fcs_fshift, r2, pot, grad, fcs_r2cut = SQR(fcs_rcut); pot_table_t *pt = &pair_pot; /* FCS near-field shifts */ fcs_pair_int(&fcs_shift, &fcs_fshift, fcs_r2cut); if (0==myid) { printf("FCS near-field shifted by: %g , %g\n", fcs_shift, fcs_fshift); } /* add near-field to potential table */ for (i=0; i<ntypes; i++) for (j=0; j<ntypes; j++) { col = i * ntypes + j; for (k=0; k < pt->len[col]; k++) { r2 = pt->begin[col] + k * pt->step[col]; if (r2 > fcs_r2cut) continue; fcs_pair_int(&pot, &grad, r2); pot -= fcs_shift; pot -= 0.5 * fcs_fshift * (r2 - fcs_r2cut); pot *= coul_eng * charge[i] * charge[j]; *PTR_2D(pt->table, k, col, pt->maxsteps, pt->ncols) += pot; } } }
real grad2(pot_table_t *pt, int col, int inc, real r2) { real r2a, istep, chi, p0, p1, p2, dv, d2v, *ptr; int k; /* check for distances shorter than minimal distance in table */ r2a = MIN(r2, pt->end[col]); r2a = r2a - pt->begin[col]; if (r2a < 0) { r2a = 0; } /* indices into potential table */ istep = pt->invstep[col]; k = (int)(r2a * istep); chi = (r2a - k * pt->step[col]) * istep; /* intermediate values */ ptr = PTR_2D(pt->table, k, col, pt->maxsteps, inc); p0 = *ptr; ptr += inc; p1 = *ptr; ptr += inc; p2 = *ptr; dv = p1 - p0; d2v = p2 - 2 * p1 + p0; /* return the gradient value */ return 2 * istep * (dv + (chi - 0.5) * d2v); }
real grad3(pot_table_t *pt, int col, int inc, real r2) { real r2a, istep, chi, p0, p1, p2, p3, *ptr; real dfac0, dfac1, dfac2, dfac3; int k; /* check for distances shorter than minimal distance in table */ /* we need one extra value at the lower end for interpolation */ r2a = MIN(r2, pt->end[col]); r2a = r2a - pt->begin[col]; if (r2a < 0) { r2a = 0; } /* indices into potential table */ istep = pt->invstep[col]; k = (int)(r2a * istep); if (k == 0) return grad2(pt, col, inc, r2); /* parabolic fit if on left border */ chi = (r2a - k * pt->step[col]) * istep; k--; /* intermediate values */ ptr = PTR_2D(pt->table, k, col, pt->maxsteps, inc); p0 = *ptr; ptr += inc; /* leftmost value */ p1 = *ptr; ptr += inc; /* next left */ p2 = *ptr; ptr += inc; /* first right */ p3 = *ptr; /* rightmost value */ /* factors for the interpolation */ dfac0 = -(1.0 / 6.0) * ((3.0 * chi - 6.0) * chi + 2.0); dfac1 = 0.5 * ((3.0 * chi - 4.0) * chi - 1.0); dfac2 = -0.5 * ((3.0 * chi - 2.0) * chi - 2.0); dfac3 = 1.0 / 6.0 * (3.0 * chi * chi - 1.0); /* return the gradient value */ // return 2. * istep * (dfac0 * p0 + dfac1 * p1 + dfac2 * p2 + dfac3 * p3); chi = 2. * istep * (dfac0 * p0 + dfac1 * p1 + dfac2 * p2 + dfac3 * p3); return chi; }
void read_pot_table2(pot_table_t *pt, int ncols, char *filename, FILE *infile) { int i, k, *len; int tablesize; real val, numstep; str255 msg; real cellsz = 0.0; len = (int *) malloc(ncols * sizeof(real)); if (len==NULL) error("allocation failed in read_pot_table"); /* read the info block of the function table */ for(i=0; i<ncols; i++) { if (3 != fscanf(infile, "%lf %lf %lf", &pt->begin[i], &pt->end[i], &pt->step[i])) { sprintf(msg, "Info line in %s corrupt.", filename); error(msg); } if (ncols==ntypes*ntypes) cellsz = MAX(cellsz,pt->end[i]); pt->invstep[i] = 1.0 / pt->step[i]; numstep = 1 + (pt->end[i] - pt->begin[i]) / pt->step[i]; len[i] = (int) (numstep+0.49); pt->maxsteps = MAX(pt->maxsteps, len[i]); /* some security against rounding errors */ if ((fabs(len[i] - numstep) >= 0.1)) { char msg[255]; sprintf(msg,"numstep = %f rounded to %d in file %s.", numstep, len[i], filename); printf(msg); } } /* allocate the function table */ /* allow some extra values at the end for interpolation */ tablesize = ncols * (pt->maxsteps+3); pt->table = (real *) malloc(tablesize * sizeof(real)); if (NULL==pt->table) { sprintf(msg,"Cannot allocate memory for function table %s.",filename); error(msg); } /* input loop */ for (i=0; i<ncols; i++) { for (k=0; k<len[i]; k++) { if (1 != fscanf(infile,"%lf", &val)) { sprintf(msg, "wrong format in file %s.", filename); error(msg); } *PTR_2D(pt->table,k,i,ncols) = val; } /* make some copies of the last value for interpolation */ for (k=len[i]; k<len[i]+3; k++) *PTR_2D(pt->table,k,i,ncols) = val; } if (ncols==ntypes) { printf("Read tabulated function %s for %d atoms types.\n", filename,ncols); } else { printf("Read tabulated function %s for %d pairs of atoms types.\n", filename,ncols); } printf("Maximal length of table is %d.\n",pt->maxsteps); r2_cut = MAX(cellsz,r2_cut); }
void read_pot_table1(pot_table_t *pt, int ncols, char *filename, FILE *infile) { int i, k; int tablesize, npot=0; real val, delta; real r2, r2_start, r2_step; str255 msg; real cellsz = 0.0; /* allocate the function table */ pt->maxsteps = PSTEP; tablesize = ncols * pt->maxsteps; pt->table = (real *) malloc(tablesize*sizeof(real)); if (NULL==pt->table) { sprintf(msg,"Cannot allocate memory for function table %s.",filename); error(msg); } /* input loop */ while (!feof(infile)) { /* still some space left? */ if (((npot%PSTEP) == 0) && (npot>0)) { pt->maxsteps += PSTEP; tablesize = ncols * pt->maxsteps; pt->table = (real *) realloc(pt->table, tablesize*sizeof(real)); if (NULL==pt->table) { sprintf(msg,"Cannot extend memory for function table %s.",filename); error(msg); } } /* read in potential */ if ( 1 != fscanf(infile,"%lf",&r2) ) break; if (npot==0) r2_start = r2; /* catch first value */ for (i=0; i<ncols; ++i) { if (( 1 != fscanf(infile,"%lf", &val))) error("Line incomplete in potential file."); *PTR_2D(pt->table,npot,i,ncols) = val; if (val!=0.0) pt->end[i] = r2; /* catch last non-zero value */ } ++npot; } r2_step = (r2 - r2_start) / (npot-1); if (ncols==ntypes) { printf("Read tabulated function %s for %d atoms types.\n", filename,ncols); } else { printf("Read tabulated function %s for %d pairs of atoms types.\n", filename,ncols); } /* fill info block, and shift potential to zero */ for (i=0; i<ncols; ++i) { pt->begin[i] = r2_start; pt->step[i] = r2_step; pt->invstep[i] = 1.0 / r2_step; delta = *PTR_2D(pt->table,(npot-1),i,ncols); /* do not shift embedding energy of EAM */ if (ncols==ntypes*ntypes) { if (delta!=0.0) { printf("Potential %1d%1d shifted by %f\n", (i/ntypes),(i%ntypes),delta); for (k=0; k<npot; ++k) *PTR_2D(pt->table,k,i,ncols) -= delta; } else { pt->end[i] += r2_step; } } if (ncols==ntypes*ntypes) cellsz = MAX(cellsz,pt->end[i]); } printf("\n"); /* The interpolation uses k+1 and k+2, so we make a few copies of the last value at the end of the table */ for (k=1; k<=5; ++k) { /* still some space left? */ if (((npot%PSTEP) == 0) && (npot>0)) { pt->maxsteps += PSTEP; tablesize = ncols * pt->maxsteps; pt->table = (real *) realloc(pt->table, tablesize*sizeof(real)); if (NULL==pt->table) { sprintf(msg,"Cannot extend memory for function table %s.",filename); error(msg); } } for (i=0; i<ncols; ++i) *PTR_2D(pt->table,npot,i,ncols) = *PTR_2D(pt->table,npot-1,i,ncols); ++npot; } r2_cut = MAX(r2_cut,cellsz); }