int Init_Lookup_Tables( reax_system *system, control_params *control, storage *workspace, mpi_datatypes *mpi_data, char *msg ) { int i, j, r; int num_atom_types; int existing_types[MAX_ATOM_TYPES], aggregated[MAX_ATOM_TYPES]; real dr; real *h, *fh, *fvdw, *fele, *fCEvd, *fCEclmb; real v0_vdw, v0_ele, vlast_vdw, vlast_ele; MPI_Comm comm; /* initializations */ v0_vdw = 0; v0_ele = 0; vlast_vdw = 0; vlast_ele = 0; comm = mpi_data->world; num_atom_types = system->reax_param.num_atom_types; dr = control->nonb_cut / control->tabulate; h = (real*) smalloc( (control->tabulate+2) * sizeof(real), "lookup:h", comm ); fh = (real*) smalloc( (control->tabulate+2) * sizeof(real), "lookup:fh", comm ); fvdw = (real*) smalloc( (control->tabulate+2) * sizeof(real), "lookup:fvdw", comm ); fCEvd = (real*) smalloc( (control->tabulate+2) * sizeof(real), "lookup:fCEvd", comm ); fele = (real*) smalloc( (control->tabulate+2) * sizeof(real), "lookup:fele", comm ); fCEclmb = (real*) smalloc( (control->tabulate+2) * sizeof(real), "lookup:fCEclmb", comm ); /* allocate Long-Range LookUp Table space based on number of atom types in the ffield file */ LR = (LR_lookup_table**) scalloc( num_atom_types, sizeof(LR_lookup_table*), "lookup:LR", comm ); for( i = 0; i < num_atom_types; ++i ) LR[i] = (LR_lookup_table*) scalloc( num_atom_types, sizeof(LR_lookup_table), "lookup:LR[i]", comm ); /* most atom types in ffield file will not exist in the current simulation. to avoid unnecessary lookup table space, determine the atom types that exist in the current simulation */ for( i = 0; i < MAX_ATOM_TYPES; ++i ) existing_types[i] = 0; for( i = 0; i < system->n; ++i ) existing_types[ system->my_atoms[i].type ] = 1; MPI_Allreduce( existing_types, aggregated, MAX_ATOM_TYPES, MPI_INT, MPI_SUM, mpi_data->world ); /* fill in the lookup table entries for existing atom types. only lower half should be enough. */ for( i = 0; i < num_atom_types; ++i ) if( aggregated[i] ) //for( j = 0; j < num_atom_types; ++j ) for( j = i; j < num_atom_types; ++j ) if( aggregated[j] ) { LR[i][j].xmin = 0; LR[i][j].xmax = control->nonb_cut; LR[i][j].n = control->tabulate + 2; LR[i][j].dx = dr; LR[i][j].inv_dx = control->tabulate / control->nonb_cut; LR[i][j].y = (LR_data*) smalloc( LR[i][j].n * sizeof(LR_data), "lookup:LR[i,j].y", comm ); LR[i][j].H = (cubic_spline_coef*) smalloc( LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].H" , comm ); LR[i][j].vdW = (cubic_spline_coef*) smalloc( LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].vdW", comm); LR[i][j].CEvd = (cubic_spline_coef*) smalloc( LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].CEvd", comm); LR[i][j].ele = (cubic_spline_coef*) smalloc( LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].ele", comm ); LR[i][j].CEclmb = (cubic_spline_coef*) smalloc( LR[i][j].n*sizeof(cubic_spline_coef), "lookup:LR[i,j].CEclmb", comm ); for( r = 1; r <= control->tabulate; ++r ) { LR_vdW_Coulomb( system, workspace, i, j, r * dr, &(LR[i][j].y[r]) ); h[r] = LR[i][j].dx; fh[r] = LR[i][j].y[r].H; fvdw[r] = LR[i][j].y[r].e_vdW; fCEvd[r] = LR[i][j].y[r].CEvd; fele[r] = LR[i][j].y[r].e_ele; fCEclmb[r] = LR[i][j].y[r].CEclmb; } // init the start-end points h[r] = LR[i][j].dx; v0_vdw = LR[i][j].y[1].CEvd; v0_ele = LR[i][j].y[1].CEclmb; fh[r] = fh[r-1]; fvdw[r] = fvdw[r-1]; fCEvd[r] = fCEvd[r-1]; fele[r] = fele[r-1]; fCEclmb[r] = fCEclmb[r-1]; vlast_vdw = fCEvd[r-1]; vlast_ele = fele[r-1]; Natural_Cubic_Spline( &h[1], &fh[1], &(LR[i][j].H[1]), control->tabulate+1, comm ); Complete_Cubic_Spline( &h[1], &fvdw[1], v0_vdw, vlast_vdw, &(LR[i][j].vdW[1]), control->tabulate+1, comm ); Natural_Cubic_Spline( &h[1], &fCEvd[1], &(LR[i][j].CEvd[1]), control->tabulate+1, comm ); Complete_Cubic_Spline( &h[1], &fele[1], v0_ele, vlast_ele, &(LR[i][j].ele[1]), control->tabulate+1, comm ); Natural_Cubic_Spline( &h[1], &fCEclmb[1], &(LR[i][j].CEclmb[1]), control->tabulate+1, comm ); } else{ LR[i][j].n = 0; } free(h); free(fh); free(fvdw); free(fCEvd); free(fele); free(fCEclmb); return 1; }
int Init_Lookup_Tables( reax_system *system, control_params *control, storage *workspace, mpi_datatypes *mpi_data, char *msg ) { int i, j, r; int num_atom_types; int existing_types[MAX_ATOM_TYPES], aggregated[MAX_ATOM_TYPES]; double dr; double *h, *fh, *fvdw, *fele, *fCEvd, *fCEclmb; double v0_vdw, v0_ele, vlast_vdw, vlast_ele; MPI_Comm comm; /* initializations */ v0_vdw = 0; v0_ele = 0; vlast_vdw = 0; vlast_ele = 0; comm = mpi_data->world; num_atom_types = system->reax_param.num_atom_types; dr = control->nonb_cut / control->tabulate; h = (double*) smalloc( (control->tabulate+2) * sizeof(double), "lookup:h", comm ); fh = (double*) smalloc( (control->tabulate+2) * sizeof(double), "lookup:fh", comm ); fvdw = (double*) smalloc( (control->tabulate+2) * sizeof(double), "lookup:fvdw", comm ); fCEvd = (double*) smalloc( (control->tabulate+2) * sizeof(double), "lookup:fCEvd", comm ); fele = (double*) smalloc( (control->tabulate+2) * sizeof(double), "lookup:fele", comm ); fCEclmb = (double*) smalloc( (control->tabulate+2) * sizeof(double), "lookup:fCEclmb", comm ); LR = (LR_lookup_table**) scalloc( num_atom_types, sizeof(LR_lookup_table*), "lookup:LR", comm ); for( i = 0; i < num_atom_types; ++i ) LR[i] = (LR_lookup_table*) scalloc( num_atom_types, sizeof(LR_lookup_table), "lookup:LR[i]", comm ); for( i = 0; i < MAX_ATOM_TYPES; ++i ) existing_types[i] = 0; for( i = 0; i < system->n; ++i ) existing_types[ system->my_atoms[i].type ] = 1; MPI_Allreduce( existing_types, aggregated, MAX_ATOM_TYPES, MPI_INT, MPI_SUM, mpi_data->world ); for( i = 0; i < num_atom_types; ++i ) { if( aggregated[i] ) { for( j = i; j < num_atom_types; ++j ) { if( aggregated[j] ) { LR[i][j].xmin = 0; LR[i][j].xmax = control->nonb_cut; LR[i][j].n = control->tabulate + 2; LR[i][j].dx = dr; LR[i][j].inv_dx = control->tabulate / control->nonb_cut; LR[i][j].y = (LR_data*) smalloc( LR[i][j].n * sizeof(LR_data), "lookup:LR[i,j].y", comm ); LR[i][j].H = (cubic_spline_coef*) smalloc( LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].H" , comm ); LR[i][j].vdW = (cubic_spline_coef*) smalloc( LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].vdW", comm); LR[i][j].CEvd = (cubic_spline_coef*) smalloc( LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].CEvd", comm); LR[i][j].ele = (cubic_spline_coef*) smalloc( LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].ele", comm ); LR[i][j].CEclmb = (cubic_spline_coef*) smalloc( LR[i][j].n*sizeof(cubic_spline_coef), "lookup:LR[i,j].CEclmb", comm ); for( r = 1; r <= control->tabulate; ++r ) { LR_vdW_Coulomb( system, workspace, control, i, j, r * dr, &(LR[i][j].y[r]) ); h[r] = LR[i][j].dx; fh[r] = LR[i][j].y[r].H; fvdw[r] = LR[i][j].y[r].e_vdW; fCEvd[r] = LR[i][j].y[r].CEvd; fele[r] = LR[i][j].y[r].e_ele; fCEclmb[r] = LR[i][j].y[r].CEclmb; } // init the start-end points h[r] = LR[i][j].dx; v0_vdw = LR[i][j].y[1].CEvd; v0_ele = LR[i][j].y[1].CEclmb; fh[r] = fh[r-1]; fvdw[r] = fvdw[r-1]; fCEvd[r] = fCEvd[r-1]; fele[r] = fele[r-1]; fCEclmb[r] = fCEclmb[r-1]; vlast_vdw = fCEvd[r-1]; vlast_ele = fele[r-1]; Natural_Cubic_Spline( &h[1], &fh[1], &(LR[i][j].H[1]), control->tabulate+1, comm ); Complete_Cubic_Spline( &h[1], &fvdw[1], v0_vdw, vlast_vdw, &(LR[i][j].vdW[1]), control->tabulate+1, comm ); Natural_Cubic_Spline( &h[1], &fCEvd[1], &(LR[i][j].CEvd[1]), control->tabulate+1, comm ); Complete_Cubic_Spline( &h[1], &fele[1], v0_ele, vlast_ele, &(LR[i][j].ele[1]), control->tabulate+1, comm ); Natural_Cubic_Spline( &h[1], &fCEclmb[1], &(LR[i][j].CEclmb[1]), control->tabulate+1, comm ); } else{ LR[i][j].n = 0; } } } } free(h); free(fh); free(fvdw); free(fCEvd); free(fele); free(fCEclmb); return 1; }