void Validate_Lists( reax_system *system, storage *workspace, reax_list **lists, int step, int n, int N, int numH, MPI_Comm comm ) { int i, comp, Hindex; reax_list *bonds, *hbonds; reallocate_data *realloc; realloc = &(workspace->realloc); /* bond list */ if( N > 0 ) { bonds = *lists + BONDS; for( i = 0; i < N; ++i ) { // if( i < n ) - we need to update ghost estimates for delayed nbrings system->my_atoms[i].num_bonds = MAX(Num_Entries(i,bonds)*2, MIN_BONDS); //if( End_Index(i, bonds) >= Start_Index(i+1, bonds)-2 ) //workspace->realloc.bonds = 1; if( i < N-1 ) comp = Start_Index(i+1, bonds); else comp = bonds->num_intrs; if( End_Index(i, bonds) > comp ) { fprintf( stderr, "step%d-bondchk failed: i=%d end(i)=%d str(i+1)=%d\n", step, i, End_Index(i,bonds), comp ); MPI_Abort( comm, INSUFFICIENT_MEMORY ); } } } /* hbonds list */ if( numH > 0 ) { hbonds = *lists + HBONDS; for( i = 0; i < n; ++i ) { Hindex = system->my_atoms[i].Hindex; if( Hindex > -1 ) { system->my_atoms[i].num_hbonds = (int)(MAX( Num_Entries(Hindex, hbonds)*SAFER_ZONE, MIN_HBONDS )); //if( Num_Entries(i, hbonds) >= //(Start_Index(i+1,hbonds)-Start_Index(i,hbonds))*0.90/*DANGER_ZONE*/){ // workspace->realloc.hbonds = 1; if( Hindex < numH-1 ) comp = Start_Index(Hindex+1, hbonds); else comp = hbonds->num_intrs; if( End_Index(Hindex, hbonds) > comp ) { fprintf(stderr,"step%d-hbondchk failed: H=%d end(H)=%d str(H+1)=%d\n", step, Hindex, End_Index(Hindex,hbonds), comp ); MPI_Abort( comm, INSUFFICIENT_MEMORY ); } } } } }
// copy bond list into old bond list void Copy_Bond_List( reax_system *system, control_params *control, list **lists ) { int i, j, top_old; list *new_bonds = (*lists) + BONDS; list *old_bonds = (*lists) + OLD_BONDS; for( top_old = 0, i = 0; i < system->N; ++i ) { Set_Start_Index( i, top_old, old_bonds ); // fprintf( stdout, "%d: ", i ); for( j = Start_Index( i, new_bonds ); j < End_Index( i, new_bonds ); ++j ) if( new_bonds->select.bond_list[j].bo_data.BO >= control->bg_cut ) { // fprintf( stderr, "%d ", new_bonds->select.bond_list[j].nbr ); old_bonds->select.bond_list[ top_old ].nbr = new_bonds->select.bond_list[j].nbr; old_bonds->select.bond_list[ top_old ].bo_data.BO = new_bonds->select.bond_list[j].bo_data.BO; top_old++; } Set_End_Index( i, top_old, old_bonds); // fprintf( stderr, "--- s: %d, e: %d\n", // Start_Index( i, old_bonds ), End_Index( i, old_bonds ) ); } }
/* This version of Compute_Total_Force computes forces from coefficients accumulated by all interaction functions. Saves enormous time & space! */ void Compute_Total_Force(reax_system *system, control_params *control, simulation_data *data, static_storage *workspace, list **lists) { int i, pj; list *bonds = (*lists) + BONDS; for (i = 0; i < system->N; ++i) for (pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj) if (i < bonds->select.bond_list[pj].nbr) { if (control->ensemble == NVE || control->ensemble == NVT) Add_dBond_to_Forces(i, pj, system, data, workspace, lists); else Add_dBond_to_Forces_NPT(i, pj, system, data, workspace, lists); } }
void Compute_Total_Force( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, mpi_datatypes *mpi_data ) { int i, pj; reax_list *bonds = (*lists) + BONDS; for( i = 0; i < system->N; ++i ) for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) if( i < bonds->select.bond_list[pj].nbr ) { if( control->virial == 0 ) Add_dBond_to_Forces( system, i, pj, workspace, lists ); else Add_dBond_to_Forces_NPT( i, pj, data, workspace, lists ); } }
/* this version of Compute_Total_Force computes forces from coefficients accumulated by all interaction functions. Saves enormous time & space! */ void Compute_Total_Force( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, mpi_datatypes *mpi_data ) { int i, pj; reax_list *bonds = (*lists) + BONDS; for( i = 0; i < system->N; ++i ) for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) if( i < bonds->select.bond_list[pj].nbr ) { if( control->virial == 0 ) Add_dBond_to_Forces( system, i, pj, workspace, lists ); else Add_dBond_to_Forces_NPT( i, pj, data, workspace, lists ); } //Print_Total_Force( system, data, workspace ); #if defined(PURE_REAX) /* now all forces are computed to their partially-final values based on the neighbors information each processor has had. final values of force on each atom needs to be computed by adding up all partially-final pieces */ Coll( system, mpi_data, workspace->f, mpi_data->mpi_rvec, sizeof(rvec)/sizeof(void), rvec_unpacker ); for( i = 0; i < system->n; ++i ) rvec_Copy( system->my_atoms[i].f, workspace->f[i] ); #if defined(TEST_FORCES) Coll( system, mpi_data, workspace->f_ele, mpi_data->mpi_rvec, rvec_unpacker); Coll( system, mpi_data, workspace->f_vdw, mpi_data->mpi_rvec, rvec_unpacker); Coll( system, mpi_data, workspace->f_be, mpi_data->mpi_rvec, rvec_unpacker ); Coll( system, mpi_data, workspace->f_lp, mpi_data->mpi_rvec, rvec_unpacker ); Coll( system, mpi_data, workspace->f_ov, mpi_data->mpi_rvec, rvec_unpacker ); Coll( system, mpi_data, workspace->f_un, mpi_data->mpi_rvec, rvec_unpacker ); Coll( system, mpi_data, workspace->f_ang, mpi_data->mpi_rvec, rvec_unpacker); Coll( system, mpi_data, workspace->f_coa, mpi_data->mpi_rvec, rvec_unpacker); Coll( system, mpi_data, workspace->f_pen, mpi_data->mpi_rvec, rvec_unpacker); Coll( system, mpi_data, workspace->f_hb, mpi_data->mpi_rvec, rvec_unpacker ); Coll( system, mpi_data, workspace->f_tor, mpi_data->mpi_rvec, rvec_unpacker); Coll( system, mpi_data, workspace->f_con, mpi_data->mpi_rvec, rvec_unpacker); #endif #endif }
void Visit_Bonds( int atom, int *mark, int *type, reax_system *system, control_params *control, list *bonds, int ignore ) { int i, t, start, end, nbr; real bo; mark[atom] = 1; t = system->atoms[atom].type; if( ignore && control->ignore[t] ) return; type[t]++; start = Start_Index( atom, bonds ); end = End_Index( atom, bonds ); for( i = start; i < end; ++i ) { nbr = bonds->select.bond_list[i].nbr; bo = bonds->select.bond_list[i].bo_data.BO; if( bo >= control->bg_cut && !mark[nbr] ) Visit_Bonds( nbr, mark, type, system, control, bonds, ignore ); } }
void Get_Molecule( int atom, molecule *m, int *mark, reax_system *system, control_params *control, list *bonds, int print, FILE *fout ) { int i, start, end; start = Start_Index( atom, bonds ); end = End_Index( atom, bonds ); if( print ) fprintf( fout, "%5d(%2s)", atom+1, system->reaxprm.sbp[ system->atoms[atom].type ].name ); mark[atom] = 1; m->atom_list[ m->atom_count++ ] = atom; m->mtypes[ system->atoms[ atom ].type ]++; for( i = start; i < end; ++i ) if( bonds->select.bond_list[i].bo_data.BO >= control->bg_cut && !mark[bonds->select.bond_list[i].nbr] ) Get_Molecule( bonds->select.bond_list[i].nbr, m, mark, system, control, bonds, print, fout ); }
void Estimate_Storage_Sizes(reax_system *system, control_params *control, list **lists, int *Htop, int *hb_top, int *bond_top, int *num_3body) { int i, j, pj; int start_i, end_i; int type_i, type_j; int ihb, jhb; real r_ij, r2; real C12, C34, C56; real BO, BO_s, BO_pi, BO_pi2; real p_boc1, p_boc2; list *far_nbrs; single_body_parameters *sbp_i, *sbp_j; two_body_parameters *twbp; far_neighbor_data *nbr_pj; reax_atom *atom_i, *atom_j; far_nbrs = *lists + FAR_NBRS; p_boc1 = system->reaxprm.gp.l[0]; p_boc2 = system->reaxprm.gp.l[1]; for (i = 0; i < system->N; ++i) { atom_i = &(system->atoms[i]); type_i = atom_i->type; start_i = Start_Index(i, far_nbrs); end_i = End_Index(i, far_nbrs); sbp_i = &(system->reaxprm.sbp[type_i]); ihb = sbp_i->p_hbond; for (pj = start_i; pj < end_i; ++pj) { nbr_pj = &(far_nbrs->select.far_nbr_list[pj]); j = nbr_pj->nbr; atom_j = &(system->atoms[j]); type_j = atom_j->type; sbp_j = &(system->reaxprm.sbp[type_j]); twbp = &(system->reaxprm.tbp[type_i][type_j]); if (nbr_pj->d <= control->r_cut) { ++(*Htop); /* hydrogen bond lists */ if (control->hb_cut > 0.1 && (ihb == 1 || ihb == 2) && nbr_pj->d <= control->hb_cut) { jhb = sbp_j->p_hbond; if (ihb == 1 && jhb == 2) ++hb_top[i]; else if (ihb == 2 && jhb == 1) ++hb_top[j]; } /* uncorrected bond orders */ if (nbr_pj->d <= control->nbr_cut) { r_ij = nbr_pj->d; r2 = SQR(r_ij); if (sbp_i->r_s > 0.0 && sbp_j->r_s > 0.0) { C12 = twbp->p_bo1 * POW(r_ij / twbp->r_s, twbp->p_bo2); BO_s = (1.0 + control->bo_cut) * EXP(C12); } else BO_s = C12 = 0.0; if (sbp_i->r_pi > 0.0 && sbp_j->r_pi > 0.0) { C34 = twbp->p_bo3 * POW(r_ij / twbp->r_p, twbp->p_bo4); BO_pi = EXP(C34); } else BO_pi = C34 = 0.0; if (sbp_i->r_pi_pi > 0.0 && sbp_j->r_pi_pi > 0.0) { C56 = twbp->p_bo5 * POW(r_ij / twbp->r_pp, twbp->p_bo6); BO_pi2 = EXP(C56); } else BO_pi2 = C56 = 0.0; /* Initially BO values are the uncorrected ones, page 1 */ BO = BO_s + BO_pi + BO_pi2; if (BO >= control->bo_cut) { ++bond_top[i]; ++bond_top[j]; } } } } } *Htop += system->N; *Htop *= SAFE_ZONE; for (i = 0; i < system->N; ++i) { hb_top[i] = MAX( hb_top[i] * SAFE_HBONDS, MIN_HBONDS ); *num_3body += SQR(bond_top[i]); bond_top[i] = MAX( bond_top[i] * 2, MIN_BONDS ); } *num_3body *= SAFE_ZONE; }
void Validate_Lists(static_storage *workspace, list **lists, int step, int n, int Hmax, int Htop, int num_bonds, int num_hbonds) { int i, flag; list *bonds, *hbonds; bonds = *lists + BONDS; hbonds = *lists + HBONDS; /* far neighbors */ if (Htop > Hmax * DANGER_ZONE) { workspace->realloc.Htop = Htop; if (Htop > Hmax) { fprintf(stderr, "step%d - ran out of space on H matrix: Htop=%d, max = %d", step, Htop, Hmax); exit(INSUFFICIENT_SPACE); } } /* bond list */ flag = -1; workspace->realloc.num_bonds = num_bonds; for (i = 0; i < n - 1; ++i) if (End_Index(i, bonds) >= Start_Index(i + 1, bonds) - 2) { workspace->realloc.bonds = 1; if (End_Index(i, bonds) > Start_Index(i + 1, bonds)) flag = i; } if (flag > -1) { fprintf(stderr, "step%d-bondchk failed: i=%d end(i)=%d str(i+1)=%d\n", step, flag, End_Index(flag, bonds), Start_Index(flag + 1, bonds)); exit(INSUFFICIENT_SPACE); } if (End_Index(i, bonds) >= bonds->num_intrs - 2) { workspace->realloc.bonds = 1; if (End_Index(i, bonds) > bonds->num_intrs) { fprintf(stderr, "step%d-bondchk failed: i=%d end(i)=%d bond_end=%d\n", step, flag, End_Index(i, bonds), bonds->num_intrs); exit(INSUFFICIENT_SPACE); } } /* hbonds list */ if (workspace->num_H > 0) { flag = -1; workspace->realloc.num_hbonds = num_hbonds; for (i = 0; i < workspace->num_H - 1; ++i) if (Num_Entries(i, hbonds) >= (Start_Index(i + 1, hbonds) - Start_Index(i, hbonds)) * DANGER_ZONE) { workspace->realloc.hbonds = 1; if (End_Index(i, hbonds) > Start_Index(i + 1, hbonds)) flag = i; } if (flag > -1) { fprintf(stderr, "step%d-hbondchk failed: i=%d end(i)=%d str(i+1)=%d\n", step, flag, End_Index(flag, hbonds), Start_Index(flag + 1, hbonds)); exit(INSUFFICIENT_SPACE); } if (Num_Entries(i, hbonds) >= (hbonds->num_intrs - Start_Index(i, hbonds)) * DANGER_ZONE) { workspace->realloc.hbonds = 1; if (End_Index(i, hbonds) > hbonds->num_intrs) { fprintf(stderr, "step%d-hbondchk failed: i=%d end(i)=%d hbondend=%d\n", step, flag, End_Index(i, hbonds), hbonds->num_intrs); exit(INSUFFICIENT_SPACE); } } } }
void Valence_Angles( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control ) { int i, j, pi, k, pk, t; int type_i, type_j, type_k; int start_j, end_j, start_pk, end_pk; int cnt, num_thb_intrs; double temp, temp_bo_jt, pBOjt7; double p_val1, p_val2, p_val3, p_val4, p_val5; double p_val6, p_val7, p_val8, p_val9, p_val10; double p_pen1, p_pen2, p_pen3, p_pen4; double p_coa1, p_coa2, p_coa3, p_coa4; double trm8, expval6, expval7, expval2theta, expval12theta, exp3ij, exp3jk; double exp_pen2ij, exp_pen2jk, exp_pen3, exp_pen4, trm_pen34, exp_coa2; double dSBO1, dSBO2, SBO, SBO2, CSBO2, SBOp, prod_SBO, vlpadj; double CEval1, CEval2, CEval3, CEval4, CEval5, CEval6, CEval7, CEval8; double CEpen1, CEpen2, CEpen3; double e_ang, e_coa, e_pen; double CEcoa1, CEcoa2, CEcoa3, CEcoa4, CEcoa5; double Cf7ij, Cf7jk, Cf8j, Cf9j; double f7_ij, f7_jk, f8_Dj, f9_Dj; double Ctheta_0, theta_0, theta_00, theta, cos_theta, sin_theta; double BOA_ij, BOA_jk; rvec force, ext_press; // Tallying variables double eng_tmp, fi_tmp[3], fj_tmp[3], fk_tmp[3]; double delij[3], delkj[3]; three_body_header *thbh; three_body_parameters *thbp; three_body_interaction_data *p_ijk, *p_kji; bond_data *pbond_ij, *pbond_jk, *pbond_jt; bond_order_data *bo_ij, *bo_jk, *bo_jt; reax_list *bonds = (*lists) + BONDS; reax_list *thb_intrs = (*lists) + THREE_BODIES; /* global parameters used in these calculations */ p_val6 = system->reax_param.gp.l[14]; p_val8 = system->reax_param.gp.l[33]; p_val9 = system->reax_param.gp.l[16]; p_val10 = system->reax_param.gp.l[17]; num_thb_intrs = 0; for( j = 0; j < system->N; ++j ) { // Ray: the first one with system->N type_j = system->my_atoms[j].type; if (type_j < 0) continue; start_j = Start_Index(j, bonds); end_j = End_Index(j, bonds); p_val3 = system->reax_param.sbp[ type_j ].p_val3; p_val5 = system->reax_param.sbp[ type_j ].p_val5; SBOp = 0, prod_SBO = 1; for( t = start_j; t < end_j; ++t ) { bo_jt = &(bonds->select.bond_list[t].bo_data); SBOp += (bo_jt->BO_pi + bo_jt->BO_pi2); temp = SQR( bo_jt->BO ); temp *= temp; temp *= temp; prod_SBO *= exp( -temp ); } if( workspace->vlpex[j] >= 0 ){ vlpadj = 0; dSBO2 = prod_SBO - 1; } else{ vlpadj = workspace->nlp[j]; dSBO2 = (prod_SBO - 1) * (1 - p_val8 * workspace->dDelta_lp[j]); } SBO = SBOp + (1 - prod_SBO) * (-workspace->Delta_boc[j] - p_val8 * vlpadj); dSBO1 = -8 * prod_SBO * ( workspace->Delta_boc[j] + p_val8 * vlpadj ); if( SBO <= 0 ) SBO2 = 0, CSBO2 = 0; else if( SBO > 0 && SBO <= 1 ) { SBO2 = pow( SBO, p_val9 ); CSBO2 = p_val9 * pow( SBO, p_val9 - 1 ); } else if( SBO > 1 && SBO < 2 ) { SBO2 = 2 - pow( 2-SBO, p_val9 ); CSBO2 = p_val9 * pow( 2 - SBO, p_val9 - 1 ); } else SBO2 = 2, CSBO2 = 0; expval6 = exp( p_val6 * workspace->Delta_boc[j] ); for( pi = start_j; pi < end_j; ++pi ) { Set_Start_Index( pi, num_thb_intrs, thb_intrs ); pbond_ij = &(bonds->select.bond_list[pi]); bo_ij = &(pbond_ij->bo_data); BOA_ij = bo_ij->BO - control->thb_cut; if( BOA_ij/*bo_ij->BO*/ > 0.0 && ( j < system->n || pbond_ij->nbr < system->n ) ) { i = pbond_ij->nbr; type_i = system->my_atoms[i].type; for( pk = start_j; pk < pi; ++pk ) { start_pk = Start_Index( pk, thb_intrs ); end_pk = End_Index( pk, thb_intrs ); for( t = start_pk; t < end_pk; ++t ) if( thb_intrs->select.three_body_list[t].thb == i ) { p_ijk = &(thb_intrs->select.three_body_list[num_thb_intrs] ); p_kji = &(thb_intrs->select.three_body_list[t]); p_ijk->thb = bonds->select.bond_list[pk].nbr; p_ijk->pthb = pk; p_ijk->theta = p_kji->theta; rvec_Copy( p_ijk->dcos_di, p_kji->dcos_dk ); rvec_Copy( p_ijk->dcos_dj, p_kji->dcos_dj ); rvec_Copy( p_ijk->dcos_dk, p_kji->dcos_di ); ++num_thb_intrs; break; } } for( pk = pi+1; pk < end_j; ++pk ) { pbond_jk = &(bonds->select.bond_list[pk]); bo_jk = &(pbond_jk->bo_data); BOA_jk = bo_jk->BO - control->thb_cut; k = pbond_jk->nbr; type_k = system->my_atoms[k].type; p_ijk = &( thb_intrs->select.three_body_list[num_thb_intrs] ); Calculate_Theta( pbond_ij->dvec, pbond_ij->d, pbond_jk->dvec, pbond_jk->d, &theta, &cos_theta ); Calculate_dCos_Theta( pbond_ij->dvec, pbond_ij->d, pbond_jk->dvec, pbond_jk->d, &(p_ijk->dcos_di), &(p_ijk->dcos_dj), &(p_ijk->dcos_dk) ); p_ijk->thb = k; p_ijk->pthb = pk; p_ijk->theta = theta; sin_theta = sin( theta ); if( sin_theta < 1.0e-5 ) sin_theta = 1.0e-5; ++num_thb_intrs; if( (j < system->n) && (BOA_jk > 0.0) && (bo_ij->BO > control->thb_cut) && (bo_jk->BO > control->thb_cut) && (bo_ij->BO * bo_jk->BO > control->thb_cutsq) ) { thbh = &( system->reax_param.thbp[ type_i ][ type_j ][ type_k ] ); for( cnt = 0; cnt < thbh->cnt; ++cnt ) { if( fabs(thbh->prm[cnt].p_val1) > 0.001 ) { thbp = &( thbh->prm[cnt] ); /* ANGLE ENERGY */ p_val1 = thbp->p_val1; p_val2 = thbp->p_val2; p_val4 = thbp->p_val4; p_val7 = thbp->p_val7; theta_00 = thbp->theta_00; exp3ij = exp( -p_val3 * pow( BOA_ij, p_val4 ) ); f7_ij = 1.0 - exp3ij; Cf7ij = p_val3 * p_val4 * pow( BOA_ij, p_val4 - 1.0 ) * exp3ij; exp3jk = exp( -p_val3 * pow( BOA_jk, p_val4 ) ); f7_jk = 1.0 - exp3jk; Cf7jk = p_val3 * p_val4 * pow( BOA_jk, p_val4 - 1.0 ) * exp3jk; expval7 = exp( -p_val7 * workspace->Delta_boc[j] ); trm8 = 1.0 + expval6 + expval7; f8_Dj = p_val5 - ( (p_val5 - 1.0) * (2.0 + expval6) / trm8 ); Cf8j = ( (1.0 - p_val5) / SQR(trm8) ) * ( p_val6 * expval6 * trm8 - (2.0 + expval6) * ( p_val6*expval6 - p_val7*expval7 ) ); theta_0 = 180.0 - theta_00 * (1.0 - exp(-p_val10 * (2.0 - SBO2))); theta_0 = DEG2RAD( theta_0 ); expval2theta = exp( -p_val2 * SQR(theta_0 - theta) ); if( p_val1 >= 0 ) expval12theta = p_val1 * (1.0 - expval2theta); else // To avoid linear Me-H-Me angles (6/6/06) expval12theta = p_val1 * -expval2theta; CEval1 = Cf7ij * f7_jk * f8_Dj * expval12theta; CEval2 = Cf7jk * f7_ij * f8_Dj * expval12theta; CEval3 = Cf8j * f7_ij * f7_jk * expval12theta; CEval4 = -2.0 * p_val1 * p_val2 * f7_ij * f7_jk * f8_Dj * expval2theta * (theta_0 - theta); Ctheta_0 = p_val10 * DEG2RAD(theta_00) * exp( -p_val10 * (2.0 - SBO2) ); CEval5 = -CEval4 * Ctheta_0 * CSBO2; CEval6 = CEval5 * dSBO1; CEval7 = CEval5 * dSBO2; CEval8 = -CEval4 / sin_theta; data->my_en.e_ang += e_ang = f7_ij * f7_jk * f8_Dj * expval12theta; /* END ANGLE ENERGY*/ /* PENALTY ENERGY */ p_pen1 = thbp->p_pen1; p_pen2 = system->reax_param.gp.l[19]; p_pen3 = system->reax_param.gp.l[20]; p_pen4 = system->reax_param.gp.l[21]; exp_pen2ij = exp( -p_pen2 * SQR( BOA_ij - 2.0 ) ); exp_pen2jk = exp( -p_pen2 * SQR( BOA_jk - 2.0 ) ); exp_pen3 = exp( -p_pen3 * workspace->Delta[j] ); exp_pen4 = exp( p_pen4 * workspace->Delta[j] ); trm_pen34 = 1.0 + exp_pen3 + exp_pen4; f9_Dj = ( 2.0 + exp_pen3 ) / trm_pen34; Cf9j = ( -p_pen3 * exp_pen3 * trm_pen34 - (2.0 + exp_pen3) * ( -p_pen3 * exp_pen3 + p_pen4 * exp_pen4 ) ) / SQR( trm_pen34 ); data->my_en.e_pen += e_pen = p_pen1 * f9_Dj * exp_pen2ij * exp_pen2jk; CEpen1 = e_pen * Cf9j / f9_Dj; temp = -2.0 * p_pen2 * e_pen; CEpen2 = temp * (BOA_ij - 2.0); CEpen3 = temp * (BOA_jk - 2.0); /* END PENALTY ENERGY */ /* COALITION ENERGY */ p_coa1 = thbp->p_coa1; p_coa2 = system->reax_param.gp.l[2]; p_coa3 = system->reax_param.gp.l[38]; p_coa4 = system->reax_param.gp.l[30]; exp_coa2 = exp( p_coa2 * workspace->Delta_val[j] ); data->my_en.e_coa += e_coa = p_coa1 / (1. + exp_coa2) * exp( -p_coa3 * SQR(workspace->total_bond_order[i]-BOA_ij) ) * exp( -p_coa3 * SQR(workspace->total_bond_order[k]-BOA_jk) ) * exp( -p_coa4 * SQR(BOA_ij - 1.5) ) * exp( -p_coa4 * SQR(BOA_jk - 1.5) ); CEcoa1 = -2 * p_coa4 * (BOA_ij - 1.5) * e_coa; CEcoa2 = -2 * p_coa4 * (BOA_jk - 1.5) * e_coa; CEcoa3 = -p_coa2 * exp_coa2 * e_coa / (1 + exp_coa2); CEcoa4 = -2 * p_coa3 * (workspace->total_bond_order[i]-BOA_ij) * e_coa; CEcoa5 = -2 * p_coa3 * (workspace->total_bond_order[k]-BOA_jk) * e_coa; /* END COALITION ENERGY */ /* FORCES */ bo_ij->Cdbo += (CEval1 + CEpen2 + (CEcoa1 - CEcoa4)); bo_jk->Cdbo += (CEval2 + CEpen3 + (CEcoa2 - CEcoa5)); workspace->CdDelta[j] += ((CEval3 + CEval7) + CEpen1 + CEcoa3); workspace->CdDelta[i] += CEcoa4; workspace->CdDelta[k] += CEcoa5; for( t = start_j; t < end_j; ++t ) { pbond_jt = &( bonds->select.bond_list[t] ); bo_jt = &(pbond_jt->bo_data); temp_bo_jt = bo_jt->BO; temp = CUBE( temp_bo_jt ); pBOjt7 = temp * temp * temp_bo_jt; bo_jt->Cdbo += (CEval6 * pBOjt7); bo_jt->Cdbopi += CEval5; bo_jt->Cdbopi2 += CEval5; } if( control->virial == 0 ) { rvec_ScaledAdd( workspace->f[i], CEval8, p_ijk->dcos_di ); rvec_ScaledAdd( workspace->f[j], CEval8, p_ijk->dcos_dj ); rvec_ScaledAdd( workspace->f[k], CEval8, p_ijk->dcos_dk ); } else { rvec_Scale( force, CEval8, p_ijk->dcos_di ); rvec_Add( workspace->f[i], force ); rvec_iMultiply( ext_press, pbond_ij->rel_box, force ); rvec_Add( data->my_ext_press, ext_press ); rvec_ScaledAdd( workspace->f[j], CEval8, p_ijk->dcos_dj ); rvec_Scale( force, CEval8, p_ijk->dcos_dk ); rvec_Add( workspace->f[k], force ); rvec_iMultiply( ext_press, pbond_jk->rel_box, force ); rvec_Add( data->my_ext_press, ext_press ); } /* tally into per-atom virials */ if( system->pair_ptr->vflag_atom || system->pair_ptr->evflag) { /* Acquire vectors */ rvec_ScaledSum( delij, 1., system->my_atoms[i].x, -1., system->my_atoms[j].x ); rvec_ScaledSum( delkj, 1., system->my_atoms[k].x, -1., system->my_atoms[j].x ); rvec_Scale( fi_tmp, -CEval8, p_ijk->dcos_di ); rvec_Scale( fj_tmp, -CEval8, p_ijk->dcos_dj ); rvec_Scale( fk_tmp, -CEval8, p_ijk->dcos_dk ); eng_tmp = e_ang + e_pen + e_coa; if( system->pair_ptr->evflag) system->pair_ptr->ev_tally(j,j,system->N,1,eng_tmp,0.0,0.0,0.0,0.0,0.0); if( system->pair_ptr->vflag_atom) system->pair_ptr->v_tally3(i,j,k,fi_tmp,fk_tmp,delij,delkj); } } } } } } Set_End_Index(pi, num_thb_intrs, thb_intrs ); } } if( num_thb_intrs >= thb_intrs->num_intrs * DANGER_ZONE ) { workspace->realloc.num_3body = num_thb_intrs; if( num_thb_intrs > thb_intrs->num_intrs ) { fprintf( stderr, "step%d-ran out of space on angle_list: top=%d, max=%d", data->step, num_thb_intrs, thb_intrs->num_intrs ); MPI_Abort( MPI_COMM_WORLD, INSUFFICIENT_MEMORY ); } } }
void Init_Forces_Tab(reax_system *system, control_params *control, simulation_data *data, static_storage *workspace, list **lists, output_controls *out_control) { int i, j, pj; int start_i, end_i; int type_i, type_j; int Htop, btop_i, btop_j, num_bonds, num_hbonds; int tmin, tmax, r; int ihb, jhb, ihb_top, jhb_top; int flag; real r_ij, r2, self_coef; real val, dif, base; real C12, C34, C56; real Cln_BOp_s, Cln_BOp_pi, Cln_BOp_pi2; real BO, BO_s, BO_pi, BO_pi2; real p_boc1, p_boc2; sparse_matrix *H; list *far_nbrs, *bonds, *hbonds; single_body_parameters *sbp_i, *sbp_j; two_body_parameters *twbp; far_neighbor_data *nbr_pj; LR_lookup_table *t; reax_atom *atom_i, *atom_j; bond_data *ibond, *jbond; bond_order_data *bo_ij, *bo_ji; far_nbrs = *lists + FAR_NBRS; bonds = *lists + BONDS; hbonds = *lists + HBONDS; H = workspace->H; Htop = 0; num_bonds = 0; num_hbonds = 0; btop_i = btop_j = 0; p_boc1 = system->reaxprm.gp.l[0]; p_boc2 = system->reaxprm.gp.l[1]; for (i = 0; i < system->N; ++i) { atom_i = &(system->atoms[i]); type_i = atom_i->type; start_i = Start_Index(i, far_nbrs); end_i = End_Index(i, far_nbrs); H->start[i] = Htop; btop_i = End_Index(i, bonds); sbp_i = &(system->reaxprm.sbp[type_i]); ihb = ihb_top = -1; if (control->hb_cut > 0 && (ihb = sbp_i->p_hbond) == 1) ihb_top = End_Index(workspace->hbond_index[i], hbonds); for (pj = start_i; pj < end_i; ++pj) { nbr_pj = &(far_nbrs->select.far_nbr_list[pj]); j = nbr_pj->nbr; atom_j = &(system->atoms[j]); flag = 0; if ((data->step - data->prev_steps) % control->reneighbor == 0) { if (nbr_pj->d <= control->r_cut) flag = 1; else flag = 0; } else if ((nbr_pj->d = Sq_Distance_on_T3(atom_i->x, atom_j->x, &(system->box), nbr_pj->dvec)) <= SQR(control->r_cut)) { nbr_pj->d = sqrt(nbr_pj->d); flag = 1; } if (flag) { type_j = system->atoms[j].type; r_ij = nbr_pj->d; sbp_j = &(system->reaxprm.sbp[type_j]); twbp = &(system->reaxprm.tbp[type_i][type_j]); self_coef = (i == j) ? 0.5 : 1.0; tmin = MIN( type_i, type_j ); tmax = MAX( type_i, type_j ); t = &(LR[tmin][tmax]); /* cubic spline interpolation */ r = (int) (r_ij * t->inv_dx); if (r == 0) ++r; base = (real) (r + 1) * t->dx; dif = r_ij - base; val = ((t->ele[r].d * dif + t->ele[r].c) * dif + t->ele[r].b) * dif + t->ele[r].a; val *= EV_to_KCALpMOL / C_ele; H->entries[Htop].j = j; H->entries[Htop].val = self_coef * val; ++Htop; /* hydrogen bond lists */ if (control->hb_cut > 0 && (ihb == 1 || ihb == 2) && nbr_pj->d <= control->hb_cut) { // fprintf( stderr, "%d %d\n", atom1, atom2 ); jhb = sbp_j->p_hbond; if (ihb == 1 && jhb == 2) { hbonds->select.hbond_list[ihb_top].nbr = j; hbonds->select.hbond_list[ihb_top].scl = 1; hbonds->select.hbond_list[ihb_top].ptr = nbr_pj; ++ihb_top; ++num_hbonds; } else if (ihb == 2 && jhb == 1) { jhb_top = End_Index(workspace->hbond_index[j], hbonds); hbonds->select.hbond_list[jhb_top].nbr = i; hbonds->select.hbond_list[jhb_top].scl = -1; hbonds->select.hbond_list[jhb_top].ptr = nbr_pj; Set_End_Index(workspace->hbond_index[j], jhb_top + 1, hbonds); ++num_hbonds; } } /* uncorrected bond orders */ if (far_nbrs->select.far_nbr_list[pj].d <= control->nbr_cut) { r2 = SQR(r_ij); if (sbp_i->r_s > 0.0 && sbp_j->r_s > 0.0) { C12 = twbp->p_bo1 * POW(r_ij / twbp->r_s, twbp->p_bo2); BO_s = (1.0 + control->bo_cut) * EXP(C12); } else BO_s = C12 = 0.0; if (sbp_i->r_pi > 0.0 && sbp_j->r_pi > 0.0) { C34 = twbp->p_bo3 * POW(r_ij / twbp->r_p, twbp->p_bo4); BO_pi = EXP(C34); } else BO_pi = C34 = 0.0; if (sbp_i->r_pi_pi > 0.0 && sbp_j->r_pi_pi > 0.0) { C56 = twbp->p_bo5 * POW(r_ij / twbp->r_pp, twbp->p_bo6); BO_pi2 = EXP(C56); } else BO_pi2 = C56 = 0.0; /* Initially BO values are the uncorrected ones, page 1 */ BO = BO_s + BO_pi + BO_pi2; if (BO >= control->bo_cut) { num_bonds += 2; /****** bonds i-j and j-i ******/ ibond = &(bonds->select.bond_list[btop_i]); btop_j = End_Index(j, bonds); jbond = &(bonds->select.bond_list[btop_j]); ibond->nbr = j; jbond->nbr = i; ibond->d = r_ij; jbond->d = r_ij; rvec_Copy(ibond->dvec, nbr_pj->dvec); rvec_Scale(jbond->dvec, -1, nbr_pj->dvec); ivec_Copy(ibond->rel_box, nbr_pj->rel_box); ivec_Scale(jbond->rel_box, -1, nbr_pj->rel_box); ibond->dbond_index = btop_i; jbond->dbond_index = btop_i; ibond->sym_index = btop_j; jbond->sym_index = btop_i; ++btop_i; Set_End_Index(j, btop_j + 1, bonds); bo_ij = &(ibond->bo_data); bo_ji = &(jbond->bo_data); bo_ji->BO = bo_ij->BO = BO; bo_ji->BO_s = bo_ij->BO_s = BO_s; bo_ji->BO_pi = bo_ij->BO_pi = BO_pi; bo_ji->BO_pi2 = bo_ij->BO_pi2 = BO_pi2; /* Bond Order page2-3, derivative of total bond order prime */ Cln_BOp_s = twbp->p_bo2 * C12 / r2; Cln_BOp_pi = twbp->p_bo4 * C34 / r2; Cln_BOp_pi2 = twbp->p_bo6 * C56 / r2; /* Only dln_BOp_xx wrt. dr_i is stored here, note that dln_BOp_xx/dr_i = -dln_BOp_xx/dr_j and all others are 0 */ rvec_Scale(bo_ij->dln_BOp_s, -bo_ij->BO_s * Cln_BOp_s, ibond->dvec); rvec_Scale(bo_ij->dln_BOp_pi, -bo_ij->BO_pi * Cln_BOp_pi, ibond->dvec); rvec_Scale(bo_ij->dln_BOp_pi2, -bo_ij->BO_pi2 * Cln_BOp_pi2, ibond->dvec); rvec_Scale(bo_ji->dln_BOp_s, -1., bo_ij->dln_BOp_s); rvec_Scale(bo_ji->dln_BOp_pi, -1., bo_ij->dln_BOp_pi); rvec_Scale(bo_ji->dln_BOp_pi2, -1., bo_ij->dln_BOp_pi2); /* Only dBOp wrt. dr_i is stored here, note that dBOp/dr_i = -dBOp/dr_j and all others are 0 */ rvec_Scale(bo_ij->dBOp, -(bo_ij->BO_s * Cln_BOp_s + bo_ij->BO_pi * Cln_BOp_pi + bo_ij->BO_pi2 * Cln_BOp_pi2), ibond->dvec); rvec_Scale(bo_ji->dBOp, -1., bo_ij->dBOp); rvec_Add(workspace->dDeltap_self[i], bo_ij->dBOp); rvec_Add(workspace->dDeltap_self[j], bo_ji->dBOp); bo_ij->BO_s -= control->bo_cut; bo_ij->BO -= control->bo_cut; bo_ji->BO_s -= control->bo_cut; bo_ji->BO -= control->bo_cut; workspace->total_bond_order[i] += bo_ij->BO; //currently total_BOp workspace->total_bond_order[j] += bo_ji->BO; //currently total_BOp bo_ij->Cdbo = bo_ij->Cdbopi = bo_ij->Cdbopi2 = 0.0; bo_ji->Cdbo = bo_ji->Cdbopi = bo_ji->Cdbopi2 = 0.0; Set_End_Index(j, btop_j + 1, bonds); } } } } H->entries[Htop].j = i; H->entries[Htop].val = system->reaxprm.sbp[type_i].eta; ++Htop; Set_End_Index(i, btop_i, bonds); if (ihb == 1) Set_End_Index(workspace->hbond_index[i], ihb_top, hbonds); } // mark the end of j list H->start[i] = Htop; /* validate lists - decide if reallocation is required! */ Validate_Lists(workspace, lists, data->step, system->N, H->m, Htop, num_bonds, num_hbonds); #if defined(DEBUG_FOCUS) fprintf( stderr, "step%d: Htop = %d, num_bonds = %d, num_hbonds = %d\n", data->step, Htop, num_bonds, num_hbonds ); //Print_Bonds( system, bonds, "sbonds.out" ); //Print_Bond_List2( system, bonds, "sbonds.out" ); //Print_Sparse_Matrix2( H, "H.out" ); #endif }
void Tabulated_vdW_Coulomb_Energy( reax_system *system,control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control ) { int i, j, pj, r, natoms, steps, update_freq, update_energies; int type_i, type_j, tmin, tmax; int start_i, end_i, orig_i, orig_j; real r_ij, base, dif; real e_vdW, e_ele; real CEvd, CEclmb; rvec temp, ext_press; far_neighbor_data *nbr_pj; reax_list *far_nbrs; LR_lookup_table *t; natoms = system->n; far_nbrs = (*lists) + FAR_NBRS; steps = data->step - data->prev_steps; update_freq = out_control->energy_update_freq; update_energies = update_freq > 0 && steps % update_freq == 0; e_ele = e_vdW = 0; for( i = 0; i < natoms; ++i ) { type_i = system->my_atoms[i].type; start_i = Start_Index(i,far_nbrs); end_i = End_Index(i,far_nbrs); orig_i = system->my_atoms[i].orig_id; for( pj = start_i; pj < end_i; ++pj ) { nbr_pj = &(far_nbrs->select.far_nbr_list[pj]); j = nbr_pj->nbr; orig_j = system->my_atoms[j].orig_id; if( nbr_pj->d <= control->nonb_cut && (j < natoms || orig_i < orig_j) ) { j = nbr_pj->nbr; type_j = system->my_atoms[j].type; r_ij = nbr_pj->d; tmin = MIN( type_i, type_j ); tmax = MAX( type_i, type_j ); t = &( LR[tmin][tmax] ); //t = &( LR[type_i][type_j] ); /* Cubic Spline Interpolation */ r = (int)(r_ij * t->inv_dx); if( r == 0 ) ++r; base = (real)(r+1) * t->dx; dif = r_ij - base; //fprintf(stderr, "r: %f, i: %d, base: %f, dif: %f\n", r, i, base, dif); if( update_energies ) { e_vdW = ((t->vdW[r].d*dif + t->vdW[r].c)*dif + t->vdW[r].b)*dif + t->vdW[r].a; e_ele = ((t->ele[r].d*dif + t->ele[r].c)*dif + t->ele[r].b)*dif + t->ele[r].a; e_ele *= system->my_atoms[i].q * system->my_atoms[j].q; data->my_en.e_vdW += e_vdW; data->my_en.e_ele += e_ele; } CEvd = ((t->CEvd[r].d*dif + t->CEvd[r].c)*dif + t->CEvd[r].b)*dif + t->CEvd[r].a; CEclmb = ((t->CEclmb[r].d*dif+t->CEclmb[r].c)*dif+t->CEclmb[r].b)*dif + t->CEclmb[r].a; CEclmb *= system->my_atoms[i].q * system->my_atoms[j].q; if( control->virial == 0 ) { rvec_ScaledAdd( workspace->f[i], -(CEvd + CEclmb), nbr_pj->dvec ); rvec_ScaledAdd( workspace->f[j], +(CEvd + CEclmb), nbr_pj->dvec ); } else { // NPT, iNPT or sNPT /* for pressure coupling, terms not related to bond order derivatives are added directly into pressure vector/tensor */ rvec_Scale( temp, CEvd + CEclmb, nbr_pj->dvec ); rvec_ScaledAdd( workspace->f[i], -1., temp ); rvec_Add( workspace->f[j], temp ); rvec_iMultiply( ext_press, nbr_pj->rel_box, temp ); rvec_Add( data->my_ext_press, ext_press ); } #ifdef TEST_ENERGY //fprintf( out_control->evdw, "%6d%6d%24.15e%24.15e%24.15e\n", fprintf( out_control->evdw, "%6d%6d%12.4f%12.4f%12.4f\n", system->my_atoms[i].orig_id, system->my_atoms[j].orig_id, r_ij, e_vdW, data->my_en.e_vdW ); //fprintf(out_control->ecou,"%6d%6d%24.15e%24.15e%24.15e%24.15e%24.15e\n", fprintf( out_control->ecou, "%6d%6d%12.4f%12.4f%12.4f%12.4f%12.4f\n", system->my_atoms[i].orig_id, system->my_atoms[j].orig_id, r_ij, system->my_atoms[i].q, system->my_atoms[j].q, e_ele, data->my_en.e_ele ); #endif #ifdef TEST_FORCES rvec_ScaledAdd( workspace->f_vdw[i], -CEvd, nbr_pj->dvec ); rvec_ScaledAdd( workspace->f_vdw[j], +CEvd, nbr_pj->dvec ); rvec_ScaledAdd( workspace->f_ele[i], -CEclmb, nbr_pj->dvec ); rvec_ScaledAdd( workspace->f_ele[j], +CEclmb, nbr_pj->dvec ); #endif } } } Compute_Polarization_Energy( system, data ); }
void BO( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control ) { int i, j, pj, type_i, type_j; int start_i, end_i, sym_index; double val_i, Deltap_i, Deltap_boc_i; double val_j, Deltap_j, Deltap_boc_j; double f1, f2, f3, f4, f5, f4f5, exp_f4, exp_f5; double exp_p1i, exp_p2i, exp_p1j, exp_p2j; double temp, u1_ij, u1_ji, Cf1A_ij, Cf1B_ij, Cf1_ij, Cf1_ji; double Cf45_ij, Cf45_ji, p_lp1; //u_ij, u_ji double A0_ij, A1_ij, A2_ij, A2_ji, A3_ij, A3_ji; double explp1, p_boc1, p_boc2; single_body_parameters *sbp_i, *sbp_j; two_body_parameters *twbp; bond_order_data *bo_ij, *bo_ji; reax_list *bonds = (*lists) + BONDS; p_boc1 = system->reax_param.gp.l[0]; p_boc2 = system->reax_param.gp.l[1]; /* Calculate Deltaprime, Deltaprime_boc values */ for( i = 0; i < system->N; ++i ) { type_i = system->my_atoms[i].type; if (type_i < 0) continue; sbp_i = &(system->reax_param.sbp[type_i]); workspace->Deltap[i] = workspace->total_bond_order[i] - sbp_i->valency; workspace->Deltap_boc[i] = workspace->total_bond_order[i] - sbp_i->valency_val; workspace->total_bond_order[i] = 0; } /* Corrected Bond Order calculations */ for( i = 0; i < system->N; ++i ) { type_i = system->my_atoms[i].type; if (type_i < 0) continue; sbp_i = &(system->reax_param.sbp[type_i]); val_i = sbp_i->valency; Deltap_i = workspace->Deltap[i]; Deltap_boc_i = workspace->Deltap_boc[i]; start_i = Start_Index(i, bonds); end_i = End_Index(i, bonds); for( pj = start_i; pj < end_i; ++pj ) { j = bonds->select.bond_list[pj].nbr; type_j = system->my_atoms[j].type; if (type_j < 0) continue; bo_ij = &( bonds->select.bond_list[pj].bo_data ); // fprintf( stderr, "\tj:%d - ubo: %8.3f\n", j+1, bo_ij->BO ); if( i < j || workspace->bond_mark[j] > 3 ) { twbp = &( system->reax_param.tbp[type_i][type_j] ); if( twbp->ovc < 0.001 && twbp->v13cor < 0.001 ) { bo_ij->C1dbo = 1.000000; bo_ij->C2dbo = 0.000000; bo_ij->C3dbo = 0.000000; bo_ij->C1dbopi = bo_ij->BO_pi; bo_ij->C2dbopi = 0.000000; bo_ij->C3dbopi = 0.000000; bo_ij->C4dbopi = 0.000000; bo_ij->C1dbopi2 = bo_ij->BO_pi2; bo_ij->C2dbopi2 = 0.000000; bo_ij->C3dbopi2 = 0.000000; bo_ij->C4dbopi2 = 0.000000; } else { val_j = system->reax_param.sbp[type_j].valency; Deltap_j = workspace->Deltap[j]; Deltap_boc_j = workspace->Deltap_boc[j]; /* on page 1 */ if( twbp->ovc >= 0.001 ) { /* Correction for overcoordination */ exp_p1i = exp( -p_boc1 * Deltap_i ); exp_p2i = exp( -p_boc2 * Deltap_i ); exp_p1j = exp( -p_boc1 * Deltap_j ); exp_p2j = exp( -p_boc2 * Deltap_j ); f2 = exp_p1i + exp_p1j; f3 = -1.0 / p_boc2 * log( 0.5 * ( exp_p2i + exp_p2j ) ); f1 = 0.5 * ( ( val_i + f2 )/( val_i + f2 + f3 ) + ( val_j + f2 )/( val_j + f2 + f3 ) ); temp = f2 + f3; u1_ij = val_i + temp; u1_ji = val_j + temp; Cf1A_ij = 0.5 * f3 * (1.0 / SQR( u1_ij ) + 1.0 / SQR( u1_ji )); Cf1B_ij = -0.5 * (( u1_ij - f3 ) / SQR( u1_ij ) + ( u1_ji - f3 ) / SQR( u1_ji )); Cf1_ij = 0.50 * ( -p_boc1 * exp_p1i / u1_ij - ((val_i+f2) / SQR(u1_ij)) * ( -p_boc1 * exp_p1i + exp_p2i / ( exp_p2i + exp_p2j ) ) + -p_boc1 * exp_p1i / u1_ji - ((val_j+f2) / SQR(u1_ji)) * ( -p_boc1 * exp_p1i + exp_p2i / ( exp_p2i + exp_p2j ) )); Cf1_ji = -Cf1A_ij * p_boc1 * exp_p1j + Cf1B_ij * exp_p2j / ( exp_p2i + exp_p2j ); } else { /* No overcoordination correction! */ f1 = 1.0; Cf1_ij = Cf1_ji = 0.0; } if( twbp->v13cor >= 0.001 ) { /* Correction for 1-3 bond orders */ exp_f4 =exp(-(twbp->p_boc4 * SQR( bo_ij->BO ) - Deltap_boc_i) * twbp->p_boc3 + twbp->p_boc5); exp_f5 =exp(-(twbp->p_boc4 * SQR( bo_ij->BO ) - Deltap_boc_j) * twbp->p_boc3 + twbp->p_boc5); f4 = 1. / (1. + exp_f4); f5 = 1. / (1. + exp_f5); f4f5 = f4 * f5; /* Bond Order pages 8-9, derivative of f4 and f5 */ Cf45_ij = -f4 * exp_f4; Cf45_ji = -f5 * exp_f5; } else { f4 = f5 = f4f5 = 1.0; Cf45_ij = Cf45_ji = 0.0; } /* Bond Order page 10, derivative of total bond order */ A0_ij = f1 * f4f5; A1_ij = -2 * twbp->p_boc3 * twbp->p_boc4 * bo_ij->BO * (Cf45_ij + Cf45_ji); A2_ij = Cf1_ij / f1 + twbp->p_boc3 * Cf45_ij; A2_ji = Cf1_ji / f1 + twbp->p_boc3 * Cf45_ji; A3_ij = A2_ij + Cf1_ij / f1; A3_ji = A2_ji + Cf1_ji / f1; /* find corrected bond orders and their derivative coef */ bo_ij->BO = bo_ij->BO * A0_ij; bo_ij->BO_pi = bo_ij->BO_pi * A0_ij *f1; bo_ij->BO_pi2= bo_ij->BO_pi2* A0_ij *f1; bo_ij->BO_s = bo_ij->BO - ( bo_ij->BO_pi + bo_ij->BO_pi2 ); bo_ij->C1dbo = A0_ij + bo_ij->BO * A1_ij; bo_ij->C2dbo = bo_ij->BO * A2_ij; bo_ij->C3dbo = bo_ij->BO * A2_ji; bo_ij->C1dbopi = f1*f1*f4*f5; bo_ij->C2dbopi = bo_ij->BO_pi * A1_ij; bo_ij->C3dbopi = bo_ij->BO_pi * A3_ij; bo_ij->C4dbopi = bo_ij->BO_pi * A3_ji; bo_ij->C1dbopi2 = f1*f1*f4*f5; bo_ij->C2dbopi2 = bo_ij->BO_pi2 * A1_ij; bo_ij->C3dbopi2 = bo_ij->BO_pi2 * A3_ij; bo_ij->C4dbopi2 = bo_ij->BO_pi2 * A3_ji; } /* neglect bonds that are < 1e-10 */ if( bo_ij->BO < 1e-10 ) bo_ij->BO = 0.0; if( bo_ij->BO_s < 1e-10 ) bo_ij->BO_s = 0.0; if( bo_ij->BO_pi < 1e-10 ) bo_ij->BO_pi = 0.0; if( bo_ij->BO_pi2 < 1e-10 ) bo_ij->BO_pi2 = 0.0; workspace->total_bond_order[i] += bo_ij->BO; //now keeps total_BO } else { /* We only need to update bond orders from bo_ji everything else is set in uncorrected_bo calculations */ sym_index = bonds->select.bond_list[pj].sym_index; bo_ji = &(bonds->select.bond_list[ sym_index ].bo_data); bo_ij->BO = bo_ji->BO; bo_ij->BO_s = bo_ji->BO_s; bo_ij->BO_pi = bo_ji->BO_pi; bo_ij->BO_pi2 = bo_ji->BO_pi2; workspace->total_bond_order[i] += bo_ij->BO;// now keeps total_BO } } } p_lp1 = system->reax_param.gp.l[15]; for( j = 0; j < system->N; ++j ){ type_j = system->my_atoms[j].type; if (type_j < 0) continue; sbp_j = &(system->reax_param.sbp[ type_j ]); workspace->Delta[j] = workspace->total_bond_order[j] - sbp_j->valency; workspace->Delta_e[j] = workspace->total_bond_order[j] - sbp_j->valency_e; workspace->Delta_boc[j] = workspace->total_bond_order[j] - sbp_j->valency_boc; workspace->Delta_val[j] = workspace->total_bond_order[j] - sbp_j->valency_val; workspace->vlpex[j] = workspace->Delta_e[j] - 2.0 * (int)(workspace->Delta_e[j]/2.0); explp1 = exp(-p_lp1 * SQR(2.0 + workspace->vlpex[j])); workspace->nlp[j] = explp1 - (int)(workspace->Delta_e[j] / 2.0); workspace->Delta_lp[j] = sbp_j->nlp_opt - workspace->nlp[j]; workspace->Clp[j] = 2.0 * p_lp1 * explp1 * (2.0 + workspace->vlpex[j]); workspace->dDelta_lp[j] = workspace->Clp[j]; if( sbp_j->mass > 21.0 ) { workspace->nlp_temp[j] = 0.5 * (sbp_j->valency_e - sbp_j->valency); workspace->Delta_lp_temp[j] = sbp_j->nlp_opt - workspace->nlp_temp[j]; workspace->dDelta_lp_temp[j] = 0.; } else { workspace->nlp_temp[j] = workspace->nlp[j]; workspace->Delta_lp_temp[j] = sbp_j->nlp_opt - workspace->nlp_temp[j]; workspace->dDelta_lp_temp[j] = workspace->Clp[j]; } } }
void Hydrogen_Bonds( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control ) { int i, j, k, pi, pk; int type_i, type_j, type_k; int start_j, end_j, hb_start_j, hb_end_j; int hblist[MAX_BONDS]; int itr, top; int num_hb_intrs = 0; ivec rel_jk; real r_ij, r_jk, theta, cos_theta, sin_xhz4, cos_xhz1, sin_theta2; real e_hb, exp_hb2, exp_hb3, CEhb1, CEhb2, CEhb3; rvec dcos_theta_di, dcos_theta_dj, dcos_theta_dk; rvec dvec_jk, force, ext_press; // rtensor temp_rtensor, total_rtensor; hbond_parameters *hbp; bond_order_data *bo_ij; bond_data *pbond_ij; far_neighbor_data *nbr_jk; reax_list *bonds, *hbonds; bond_data *bond_list; hbond_data *hbond_list; // tally variables real fi_tmp[3], fk_tmp[3], delij[3], delkj[3]; bonds = (*lists) + BONDS; bond_list = bonds->select.bond_list; hbonds = (*lists) + HBONDS; hbond_list = hbonds->select.hbond_list; /* loops below discover the Hydrogen bonds between i-j-k triplets. here j is H atom and there has to be some bond between i and j. Hydrogen bond is between j and k. so in this function i->X, j->H, k->Z when we map variables onto the ones in the handout.*/ for( j = 0; j < system->n; ++j ) /* j has to be of type H */ if( system->reax_param.sbp[system->my_atoms[j].type].p_hbond == 1 ) { /*set j's variables */ type_j = system->my_atoms[j].type; start_j = Start_Index(j, bonds); end_j = End_Index(j, bonds); hb_start_j = Start_Index( system->my_atoms[j].Hindex, hbonds ); hb_end_j = End_Index( system->my_atoms[j].Hindex, hbonds ); top = 0; for( pi = start_j; pi < end_j; ++pi ) { pbond_ij = &( bond_list[pi] ); i = pbond_ij->nbr; bo_ij = &(pbond_ij->bo_data); type_i = system->my_atoms[i].type; if( system->reax_param.sbp[type_i].p_hbond == 2 && bo_ij->BO >= HB_THRESHOLD ) hblist[top++] = pi; } // fprintf( stderr, "j: %d, top: %d, hb_start_j: %d, hb_end_j:%d\n", // j, top, hb_start_j, hb_end_j ); for( pk = hb_start_j; pk < hb_end_j; ++pk ) { /* set k's varibles */ k = hbond_list[pk].nbr; type_k = system->my_atoms[k].type; nbr_jk = hbond_list[pk].ptr; r_jk = nbr_jk->d; rvec_Scale( dvec_jk, hbond_list[pk].scl, nbr_jk->dvec ); for( itr = 0; itr < top; ++itr ) { pi = hblist[itr]; pbond_ij = &( bonds->select.bond_list[pi] ); i = pbond_ij->nbr; if( system->my_atoms[i].orig_id != system->my_atoms[k].orig_id ) { bo_ij = &(pbond_ij->bo_data); type_i = system->my_atoms[i].type; r_ij = pbond_ij->d; hbp = &(system->reax_param.hbp[ type_i ][ type_j ][ type_k ]); ++num_hb_intrs; Calculate_Theta( pbond_ij->dvec, pbond_ij->d, dvec_jk, r_jk, &theta, &cos_theta ); /* the derivative of cos(theta) */ Calculate_dCos_Theta( pbond_ij->dvec, pbond_ij->d, dvec_jk, r_jk, &dcos_theta_di, &dcos_theta_dj, &dcos_theta_dk ); /* hyrogen bond energy*/ sin_theta2 = sin( theta/2.0 ); sin_xhz4 = SQR(sin_theta2); sin_xhz4 *= sin_xhz4; cos_xhz1 = ( 1.0 - cos_theta ); exp_hb2 = exp( -hbp->p_hb2 * bo_ij->BO ); exp_hb3 = exp( -hbp->p_hb3 * ( hbp->r0_hb / r_jk + r_jk / hbp->r0_hb - 2.0 ) ); data->my_en.e_hb += e_hb = hbp->p_hb1 * (1.0 - exp_hb2) * exp_hb3 * sin_xhz4; CEhb1 = hbp->p_hb1 * hbp->p_hb2 * exp_hb2 * exp_hb3 * sin_xhz4; CEhb2 = -hbp->p_hb1/2.0 * (1.0 - exp_hb2) * exp_hb3 * cos_xhz1; CEhb3 = -hbp->p_hb3 * (-hbp->r0_hb / SQR(r_jk) + 1.0 / hbp->r0_hb) * e_hb; /*fprintf( stdout, "%6d%6d%6d%12.6f%12.6f%12.6f%12.6f%12.6f%12.6f%12.6f%12.6f%12.6f\n", system->my_atoms[i].orig_id, system->my_atoms[j].orig_id, system->my_atoms[k].orig_id, r_jk, theta, hbp->p_hb1, exp_hb2, hbp->p_hb3, hbp->r0_hb, exp_hb3, sin_xhz4, e_hb ); */ /* hydrogen bond forces */ bo_ij->Cdbo += CEhb1; // dbo term if( control->virial == 0 ) { // dcos terms rvec_ScaledAdd( workspace->f[i], +CEhb2, dcos_theta_di ); rvec_ScaledAdd( workspace->f[j], +CEhb2, dcos_theta_dj ); rvec_ScaledAdd( workspace->f[k], +CEhb2, dcos_theta_dk ); // dr terms rvec_ScaledAdd( workspace->f[j], -CEhb3/r_jk, dvec_jk ); rvec_ScaledAdd( workspace->f[k], +CEhb3/r_jk, dvec_jk ); } else { /* for pressure coupling, terms that are not related to bond order derivatives are added directly into pressure vector/tensor */ rvec_Scale( force, +CEhb2, dcos_theta_di ); // dcos terms rvec_Add( workspace->f[i], force ); rvec_iMultiply( ext_press, pbond_ij->rel_box, force ); rvec_ScaledAdd( data->my_ext_press, 1.0, ext_press ); rvec_ScaledAdd( workspace->f[j], +CEhb2, dcos_theta_dj ); ivec_Scale( rel_jk, hbond_list[pk].scl, nbr_jk->rel_box ); rvec_Scale( force, +CEhb2, dcos_theta_dk ); rvec_Add( workspace->f[k], force ); rvec_iMultiply( ext_press, rel_jk, force ); rvec_ScaledAdd( data->my_ext_press, 1.0, ext_press ); // dr terms rvec_ScaledAdd( workspace->f[j], -CEhb3/r_jk, dvec_jk ); rvec_Scale( force, CEhb3/r_jk, dvec_jk ); rvec_Add( workspace->f[k], force ); rvec_iMultiply( ext_press, rel_jk, force ); rvec_ScaledAdd( data->my_ext_press, 1.0, ext_press ); } /* tally into per-atom virials */ if (system->pair_ptr->vflag_atom || system->pair_ptr->evflag) { rvec_ScaledSum( delij, 1., system->my_atoms[i].x, -1., system->my_atoms[j].x ); rvec_ScaledSum( delkj, 1., system->my_atoms[k].x, -1., system->my_atoms[j].x ); rvec_Scale(fi_tmp, CEhb2, dcos_theta_di); rvec_Scale(fk_tmp, CEhb2, dcos_theta_dk); rvec_ScaledAdd(fk_tmp, CEhb3/r_jk, dvec_jk); system->pair_ptr->ev_tally3(i,j,k,e_hb,0.0,fi_tmp,fk_tmp,delij,delkj); } #ifdef TEST_ENERGY /* fprintf( out_control->ehb, "%24.15e%24.15e%24.15e\n%24.15e%24.15e%24.15e\n%24.15e%24.15e%24.15e\n", dcos_theta_di[0], dcos_theta_di[1], dcos_theta_di[2], dcos_theta_dj[0], dcos_theta_dj[1], dcos_theta_dj[2], dcos_theta_dk[0], dcos_theta_dk[1], dcos_theta_dk[2]); fprintf( out_control->ehb, "%24.15e%24.15e%24.15e\n", CEhb1, CEhb2, CEhb3 ); */ fprintf( out_control->ehb, //"%6d%6d%6d%24.15e%24.15e%24.15e%24.15e%24.15e\n", "%6d%6d%6d%12.4f%12.4f%12.4f%12.4f%12.4f\n", system->my_atoms[i].orig_id, system->my_atoms[j].orig_id, system->my_atoms[k].orig_id, r_jk, theta, bo_ij->BO, e_hb, data->my_en.e_hb ); #endif #ifdef TEST_FORCES Add_dBO( system, lists, j, pi, +CEhb1, workspace->f_hb ); //dbo term // dcos terms rvec_ScaledAdd( workspace->f_hb[i], +CEhb2, dcos_theta_di ); rvec_ScaledAdd( workspace->f_hb[j], +CEhb2, dcos_theta_dj ); rvec_ScaledAdd( workspace->f_hb[k], +CEhb2, dcos_theta_dk ); // dr terms rvec_ScaledAdd( workspace->f_hb[j], -CEhb3/r_jk, dvec_jk ); rvec_ScaledAdd( workspace->f_hb[k], +CEhb3/r_jk, dvec_jk ); #endif } } } } #if defined(DEBUG) fprintf( stderr, "Number of hydrogen bonds: %d\n", num_hb_intrs ); fprintf( stderr, "Hydrogen Bond Energy: %g\n", data->my_en.e_hb ); fprintf( stderr, "hydbonds: ext_press (%24.15e %24.15e %24.15e)\n", data->ext_press[0], data->ext_press[1], data->ext_press[2] ); #endif }
void vdW_Coulomb_Energy( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control ) { int i, j, pj, natoms; int start_i, end_i, flag; rc_tagint orig_i, orig_j; double p_vdW1, p_vdW1i; double powr_vdW1, powgi_vdW1; double tmp, r_ij, fn13, exp1, exp2; double Tap, dTap, dfn13, CEvd, CEclmb, de_core; double dr3gamij_1, dr3gamij_3; double e_ele, e_vdW, e_core, SMALL = 0.0001; double e_lg, de_lg, r_ij5, r_ij6, re6; rvec temp, ext_press; two_body_parameters *twbp; far_neighbor_data *nbr_pj; reax_list *far_nbrs; // Tallying variables: double pe_vdw, f_tmp, delij[3]; natoms = system->n; far_nbrs = (*lists) + FAR_NBRS; p_vdW1 = system->reax_param.gp.l[28]; p_vdW1i = 1.0 / p_vdW1; e_core = 0; e_vdW = 0; e_lg = de_lg = 0.0; for( i = 0; i < natoms; ++i ) { if (system->my_atoms[i].type < 0) continue; start_i = Start_Index(i, far_nbrs); end_i = End_Index(i, far_nbrs); orig_i = system->my_atoms[i].orig_id; for( pj = start_i; pj < end_i; ++pj ) { nbr_pj = &(far_nbrs->select.far_nbr_list[pj]); j = nbr_pj->nbr; if (system->my_atoms[j].type < 0) continue; orig_j = system->my_atoms[j].orig_id; flag = 0; if(nbr_pj->d <= control->nonb_cut) { if (j < natoms) flag = 1; else if (orig_i < orig_j) flag = 1; else if (orig_i == orig_j) { if (nbr_pj->dvec[2] > SMALL) flag = 1; else if (fabs(nbr_pj->dvec[2]) < SMALL) { if (nbr_pj->dvec[1] > SMALL) flag = 1; else if (fabs(nbr_pj->dvec[1]) < SMALL && nbr_pj->dvec[0] > SMALL) flag = 1; } } } if (flag) { r_ij = nbr_pj->d; twbp = &(system->reax_param.tbp[ system->my_atoms[i].type ] [ system->my_atoms[j].type ]); Tap = workspace->Tap[7] * r_ij + workspace->Tap[6]; Tap = Tap * r_ij + workspace->Tap[5]; Tap = Tap * r_ij + workspace->Tap[4]; Tap = Tap * r_ij + workspace->Tap[3]; Tap = Tap * r_ij + workspace->Tap[2]; Tap = Tap * r_ij + workspace->Tap[1]; Tap = Tap * r_ij + workspace->Tap[0]; dTap = 7*workspace->Tap[7] * r_ij + 6*workspace->Tap[6]; dTap = dTap * r_ij + 5*workspace->Tap[5]; dTap = dTap * r_ij + 4*workspace->Tap[4]; dTap = dTap * r_ij + 3*workspace->Tap[3]; dTap = dTap * r_ij + 2*workspace->Tap[2]; dTap += workspace->Tap[1]/r_ij; /*vdWaals Calculations*/ if(system->reax_param.gp.vdw_type==1 || system->reax_param.gp.vdw_type==3) { // shielding powr_vdW1 = pow(r_ij, p_vdW1); powgi_vdW1 = pow( 1.0 / twbp->gamma_w, p_vdW1); fn13 = pow( powr_vdW1 + powgi_vdW1, p_vdW1i ); exp1 = exp( twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); exp2 = exp( 0.5 * twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); e_vdW = twbp->D * (exp1 - 2.0 * exp2); data->my_en.e_vdW += Tap * e_vdW; dfn13 = pow( powr_vdW1 + powgi_vdW1, p_vdW1i - 1.0) * pow(r_ij, p_vdW1 - 2.0); CEvd = dTap * e_vdW - Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * (exp1 - exp2) * dfn13; } else{ // no shielding exp1 = exp( twbp->alpha * (1.0 - r_ij / twbp->r_vdW) ); exp2 = exp( 0.5 * twbp->alpha * (1.0 - r_ij / twbp->r_vdW) ); e_vdW = twbp->D * (exp1 - 2.0 * exp2); data->my_en.e_vdW += Tap * e_vdW; CEvd = dTap * e_vdW - Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * (exp1 - exp2) / r_ij; } if(system->reax_param.gp.vdw_type==2 || system->reax_param.gp.vdw_type==3) { // innner wall e_core = twbp->ecore * exp(twbp->acore * (1.0-(r_ij/twbp->rcore))); data->my_en.e_vdW += Tap * e_core; de_core = -(twbp->acore/twbp->rcore) * e_core; CEvd += dTap * e_core + Tap * de_core / r_ij; // lg correction, only if lgvdw is yes if (control->lgflag) { r_ij5 = pow( r_ij, 5.0 ); r_ij6 = pow( r_ij, 6.0 ); re6 = pow( twbp->lgre, 6.0 ); e_lg = -(twbp->lgcij/( r_ij6 + re6 )); data->my_en.e_vdW += Tap * e_lg; de_lg = -6.0 * e_lg * r_ij5 / ( r_ij6 + re6 ) ; CEvd += dTap * e_lg + Tap * de_lg / r_ij; } } /*Coulomb Calculations*/ dr3gamij_1 = ( r_ij * r_ij * r_ij + twbp->gamma ); dr3gamij_3 = pow( dr3gamij_1 , 0.33333333333333 ); tmp = Tap / dr3gamij_3; data->my_en.e_ele += e_ele = C_ele * system->my_atoms[i].q * system->my_atoms[j].q * tmp; CEclmb = C_ele * system->my_atoms[i].q * system->my_atoms[j].q * ( dTap - Tap * r_ij / dr3gamij_1 ) / dr3gamij_3; /* tally into per-atom energy */ if( system->pair_ptr->evflag || system->pair_ptr->vflag_atom) { pe_vdw = Tap * (e_vdW + e_core + e_lg); rvec_ScaledSum( delij, 1., system->my_atoms[i].x, -1., system->my_atoms[j].x ); f_tmp = -(CEvd + CEclmb); system->pair_ptr->ev_tally(i,j,natoms,1,pe_vdw,e_ele, f_tmp,delij[0],delij[1],delij[2]); } if( control->virial == 0 ) { rvec_ScaledAdd( workspace->f[i], -(CEvd + CEclmb), nbr_pj->dvec ); rvec_ScaledAdd( workspace->f[j], +(CEvd + CEclmb), nbr_pj->dvec ); } else { /* NPT, iNPT or sNPT */ rvec_Scale( temp, CEvd + CEclmb, nbr_pj->dvec ); rvec_ScaledAdd( workspace->f[i], -1., temp ); rvec_Add( workspace->f[j], temp ); rvec_iMultiply( ext_press, nbr_pj->rel_box, temp ); rvec_Add( data->my_ext_press, ext_press ); } } } } Compute_Polarization_Energy( system, data ); }
void Report_Bond_Change( reax_system *system, control_params *control, static_storage *workspace, list *old_bonds, list *new_bonds, int a1, int a2, int flag, FILE *fout ) { int i; int rev1, rev2; int mol1 = -1, mol2 = -1; // which molecule the atom belongs to, 0: Silica, 1: Water rev1 = workspace->orig_id[a1]; rev2 = workspace->orig_id[a2]; if( !strcmp( system->atoms[a1].name, " Si" ) || !strcmp( system->atoms[a1].name, " O" ) ) mol1 = 0; else mol1 = 1; if( !strcmp( system->atoms[a2].name, " Si" ) || !strcmp( system->atoms[a2].name, " O" ) ) mol2 = 0; else mol2 = 1; if( mol1 == 0 && mol2 == 0 ) { // silica-silica if( flag ) fprintf( fout, "silica bond formation:" ); else fprintf( fout, "silica bond breakage :" ); fprintf( fout, "%5d(%s)-%5d(%s)\n", rev1, system->atoms[a1].name, rev2, system->atoms[a2].name ); } else if( mol1 == 1 && mol2 == 1 ) { // water-water if( flag ) fprintf( fout, "water bond formation:" ); else fprintf( fout, "water bond breakage :" ); fprintf( fout, "%5d(%s)-%5d(%s)\n", rev1, system->atoms[a1].name, rev2, system->atoms[a2].name ); } else { // water-silica! if( flag ) fprintf( fout, "SILICA-WATER bond formation:" ); else fprintf( fout, "SILICA-WATER bond breakage :" ); fprintf( fout, "%5d(%s)-%5d(%s)\n", rev1, system->atoms[a1].name, rev2, system->atoms[a2].name ); fprintf( fout, "%5d(%s) was connected to:", rev1, system->atoms[a1].name ); for( i = Start_Index(a1, old_bonds); i < End_Index(a1, old_bonds); ++i ) if( old_bonds->select.bond_list[i].bo_data.BO >= control->bg_cut ) fprintf( fout, " %5d(%s)", workspace->orig_id[ old_bonds->select.bond_list[i].nbr ], system->atoms[ old_bonds->select.bond_list[i].nbr ].name ); fprintf( fout, "\n" ); fprintf( fout, "%5d(%s) was connected to:", rev2, system->atoms[a2].name ); for( i = Start_Index(a2, old_bonds); i < End_Index(a2, old_bonds); ++i ) if( old_bonds->select.bond_list[i].bo_data.BO >= control->bg_cut ) fprintf( fout, " %5d(%s)", workspace->orig_id[ old_bonds->select.bond_list[i].nbr ], system->atoms[ old_bonds->select.bond_list[i].nbr ].name ); fprintf( fout, "\n" ); } }
void Compute_Bond_Boost_Force(reax_system *system, control_params *control, simulation_data *data, static_storage *workspace, list **lists, output_controls *out_control) { int i, j, pj; int type_i, type_j; int adatom, adatom2; // label the boost atom int nbond, nrad; // Nb int start_i, end_i; real e, emax, r, re, r_max; // eta, eta_max, r, r_e real bo; real A, dA, V; // A(\eta^max), and \Delta A(\eta^max) real *rv, *rv_max; real q, P1, vmax; // q, P1 in equation 13 real S1, S2, f1, f2, C1, C2; real bf; // boost force scale rvec df; // boost force reax_atom *atom1, *atom2; bond_order_data *bo_ij; two_body_parameters *twbp; list *bonds; nrad = Find_Radicals(system, control, data, workspace, lists, out_control); //printf("-------------------------step %d -----------------\n", data->step); bonds = (*lists) + BONDS; // bond boost parameters q = control->bboost_q; // should read this from control file P1 = control->bboost_P1; vmax = control->bboost_Vmax; // initiate parameters e = 0; adatom = 0; adatom2 = 0; nbond = 0; emax = 0.0; bo = 0.0; re = 0.001; A = 0.0; dA = 0.0; r_max = 0.0; // first get the max bond order for( i=0; i < system->N; ++i ) { re = 0.001; start_i = Start_Index(i, bonds); end_i = End_Index(i, bonds); for( pj = start_i; pj < end_i; ++pj ){ if( i < bonds->select.bond_list[pj].nbr ) { j = bonds->select.bond_list[pj].nbr; type_i = system->atoms[i].type; type_j = system->atoms[j].type; twbp = &( system->reaxprm.tbp[type_i][type_j] ); bo_ij = &( bonds->select.bond_list[pj].bo_data ); re = twbp->r_e; // get r_e from ffield.ext r = bonds->select.bond_list[pj].d; e = (r - re)/re; // eta //printf("r = %f, re = %f, e = %f\n", r, re, e); bo = bo_ij->BO; if ( (fabs (emax) < fabs(e)) & (bo > q)) { emax = e; adatom = i; adatom2 = j; } } } } /* printf("atom1 = %s ", system->reaxprm.sbp[ system->atoms[adatom].type ].name); printf("atom2 = %s ", system->reaxprm.sbp[ system->atoms[adatom2].type ].name); printf("bo = %f\n", bo); */ V = 0.0; // boost energy if (fabs(emax) < q && nrad == 0) { i = adatom; vmax = control->bboost_Vmax; // calculate A, and dA S1 = emax/q; S2 = S1 * S1; C1 = 1 - (emax/q)*(emax/q); C2 = 1 - P1*P1*S2; A = C1 * C1 / C2; /* printf("S1 = %f, S2 = %f ", S1, S2); printf("C1 = %f, C2 = %f ", C1, C2); printf("A = %f, emax = %f\n", A, emax); */ start_i = Start_Index(i, bonds); end_i = End_Index(i, bonds); for( pj = start_i; pj < end_i; ++pj ) { if( i < bonds->select.bond_list[pj].nbr ) { bo_ij = &( bonds->select.bond_list[pj].bo_data ); bo = bo_ij->BO; if (bo > 0.3) nbond += 1; } } for( pj = start_i; pj < end_i; ++pj ) { if( i < bonds->select.bond_list[pj].nbr ) { bo_ij = &( bonds->select.bond_list[pj].bo_data ); bo = bo_ij->BO; if (bo > 0.3) { j = bonds->select.bond_list[pj].nbr; r = bonds->select.bond_list[pj].d; rv = bonds->select.bond_list[pj].dvec; type_i = system->atoms[i].type; type_j = system->atoms[j].type; twbp = &( system->reaxprm.tbp[type_i][type_j] ); vmax = twbp->v_max; re = twbp->r_e; // get r_e from ffield.ext e = (r - re)/re; // eta C1 = 1 - e*e/(q*q); V += vmax / nbond * C1; bf = 2*A*vmax*e/(nbond*q*re); /* printf("e = %.3f, emax = %.3f, C1 = %.3f, re = %.3f, V = %.3f, A = %.3f bf = %.3f, vmax = %.3f, \n",\ e, emax, C1, re, V, A, bf, vmax); */ if (fabs(e - emax) < 0.00001) { C2 = 1 - e*e*P1*P1/(q*q); f1 = 2/(q*re); f2 = f1/2*P1*P1; dA = 2*e*C1/C2*(f1 - f2*C1/C2); rv_max = bonds->select.bond_list[pj].dvec; r_max = bonds->select.bond_list[pj].d;; } rvec_Scale(df, bf, rv); //rvec_Scale(df, 1/r, df); // assign the boost force atom1 = &( system->atoms[i] ); atom2 = &( system->atoms[j] ); /* printf("ofx = %8.3f ofy = %8.3f ofz = %8.3f \n", system->atoms[i].f[0],\ system->atoms[i].f[1], system->atoms[i].f[2]); */ rvec_Add(system->atoms[i].f, df); //printf(" fx = %8.3f fy = %8.3f fz = %8.3f \n", df[0], df[1], df[2]); /* rvec_Scale(df, -1, df); rvec_Add(system->atoms[j].f, df); */ } } } // add the contribution of evalope function A bf = dA * V; rvec_Scale(df, bf, rv_max); //rvec_Scale(df, 1/r_max, df); //printf("Max bf = %8.3f\n", bf); /* printf("Mfx = %8.3f Mfy = %8.3f Mfz = %8.3f dA = %8.3f V = %8.3f emax = %8.3f \n",\ df[0], df[1], df[2], dA, V, emax); */ atom1 = &( system->atoms[i] ); rvec_Add(system->atoms[i].f, df); } fprintf( out_control->bboost, "%-10d%6d%6d%10.4f%10.4f%10.4f", \ data->step, adatom + 1, adatom2 + 1, bo, emax, A*V ); fprintf( out_control->bboost, " %4s %4s\n", \ system->reaxprm.sbp[ system->atoms[adatom].type ].name, system->reaxprm.sbp[ system->atoms[adatom2].type ].name); fflush( out_control->bboost); }
// ASSUMPTION: Bond lists are sorted int Compare_Bond_Lists( int atom, control_params *control, list **lists ) { int oldp, newp; list *new_bonds = (*lists) + BONDS; list *old_bonds = (*lists) + OLD_BONDS; /*fprintf( stdout, "\n%d\nold_bonds:", atom ); for( oldp = Start_Index( atom, old_bonds ); oldp < End_Index( atom, old_bonds ); ++oldp ) if( old_bonds->select.bond_list[oldp].bo_data.BO >= control->bg_cut ) fprintf( stdout, "%5d", old_bonds->select.bond_list[oldp].nbr ); fprintf( stdout, "\nnew_bonds:" ); for( newp = Start_Index( atom, new_bonds ); newp < End_Index( atom, new_bonds ); ++newp ) if( new_bonds->select.bond_list[newp].bo_data.BO >= control->bg_cut ) fprintf( stdout, "%5d", new_bonds->select.bond_list[newp].nbr );*/ for( oldp = Start_Index( atom, old_bonds ), newp = Start_Index( atom, new_bonds ); oldp < End_Index(atom, old_bonds) || newp < End_Index(atom, new_bonds); oldp = MIN( oldp + 1, End_Index( atom, old_bonds ) ), newp = MIN( newp + 1, End_Index( atom, new_bonds ) ) ) { while( oldp < End_Index( atom, old_bonds ) && old_bonds->select.bond_list[oldp].bo_data.BO < control->bg_cut ) ++oldp; while( newp < End_Index( atom, new_bonds ) && new_bonds->select.bond_list[newp].bo_data.BO < control->bg_cut ) ++newp; /*fprintf( fout, "%d, oldp: %d - %d, newp: %d - %d", atom, oldp, old_bonds->select.bond_list[oldp].nbr, newp, new_bonds->select.bond_list[newp].nbr );*/ if( oldp < End_Index( atom, old_bonds ) ) { /* there are some other bonds in the old list */ if( newp < End_Index( atom, new_bonds ) ) { if( old_bonds->select.bond_list[oldp].nbr != new_bonds->select.bond_list[newp].nbr ) { //fprintf( fout, " --> case1, return 1\n" ); return 1; } } else { /* there is no other bond in the new list */ //fprintf( fout, " --> case2, return 1\n" ); return 1; } } else { /* there are no more bonds in old_bond list */ if( newp < End_Index( atom, new_bonds ) ) { /* there is at least one other bond in the new list */ //fprintf( fout, " --> case 3, return 1\n" ); return 1; } else { /* there is no other bond in the new list, either */ //fprintf( fout, " --> case 4, return 0\n" ); return 0; } } } return 0; }
void Analyze_Silica( reax_system *system, control_params *control, simulation_data *data, static_storage *workspace, list **lists, FILE *fout ) { int atom, i, j, k, pi, pk, pk_j, newp, coord; int O_SI_O_count, SI_O_SI_count; int si_coord[10], ox_coord[10]; real O_SI_O, SI_O_SI; list *new_bonds = (*lists) + BONDS; list *thb_intrs = (*lists) + THREE_BODIES; Analyze_Fragments( system, control, data, workspace, lists, fout, 0 ); /* analyze atom coordinations */ for( i = 0; i < 10; ++i ) si_coord[i] = ox_coord[i] = 0; for( atom = 0; atom < system->N; ++atom ) { coord = 0; for( newp = Start_Index( atom, new_bonds ); newp < End_Index( atom, new_bonds ); ++newp ) if( new_bonds->select.bond_list[newp].bo_data.BO >= control->bg_cut ) ++coord; if( system->atoms[ atom ].type == SI_ATOM ) { /*if( coord == 4 ) full_coord_SI++; else less_coord_SI++;*/ ++si_coord[coord]; } else if( system->atoms[ atom ].type == O_ATOM ) { /*if( coord == 2 ) full_coord_O++; else less_coord_O++;*/ ++ox_coord[coord]; } } /* fprintf( fout, "\nFour Coordinated SI: %.2f%\n", (double)full_coord_SI / (full_coord_SI + less_coord_SI) * 100. ); fprintf( fout, "Four Coordinated O : %.2f%\n", (double)full_coord_O / (full_coord_O + less_coord_O ) * 100. ); */ fprintf( fout, "Silicon coordinations:\n" ); for( i = 1; i < 10; ++i ) if( si_coord[i] ) fprintf( fout, "\t%d-coord: %d\n", i, si_coord[i] ); fprintf( fout, "\nOxygen coordinations:\n" ); for( i = 1; i < 10; ++i ) if( ox_coord[i] ) fprintf( fout, "\t%d-coord: %d\n", i, ox_coord[i] ); /* analyze bond angles */ O_SI_O = 0; O_SI_O_count = 0; SI_O_SI = 0; SI_O_SI_count = 0; for( j = 0; j < system->N; ++j ) if( system->atoms[j].type == O_ATOM || system->atoms[j].type == SI_ATOM ) for( pi = Start_Index(j, new_bonds); pi < End_Index(j, new_bonds); ++pi ) if( new_bonds->select.bond_list[pi].bo_data.BO >= control->bg_cut ) { i = new_bonds->select.bond_list[pi].nbr; if(system->atoms[i].type==O_ATOM || system->atoms[i].type==SI_ATOM) { for( pk = Start_Index( pi, thb_intrs ); pk < End_Index( pi, thb_intrs ); ++pk ) { k = thb_intrs->select.three_body_list[pk].thb; pk_j = thb_intrs->select.three_body_list[pk].pthb; // get k's pointer on j's bond list if( new_bonds->select.bond_list[pk_j].bo_data.BO >= control->bg_cut ) { // physical j&k bond /*fprintf( fout, "%5d(%d) %5d(%d) %5d(%d) %8.3f\n", i, system->atoms[i].type, j, system->atoms[j].type, k, system->atoms[k].type, thb_intrs->select.three_body_list[pk].theta );*/ if( system->atoms[i].type == O_ATOM && system->atoms[j].type == SI_ATOM && system->atoms[k].type == O_ATOM ){ O_SI_O_count++; O_SI_O += thb_intrs->select.three_body_list[pk].theta; } else if ( system->atoms[i].type == SI_ATOM && system->atoms[j].type == O_ATOM && system->atoms[k].type == SI_ATOM ){ SI_O_SI_count++; SI_O_SI += thb_intrs->select.three_body_list[pk].theta; } } } } } fprintf( fout, "\nAverage O-Si-O angle: %8.2f\n", RAD2DEG(O_SI_O / O_SI_O_count) ); fprintf( fout, "Average Si-O-Si angle: %8.2f\n\n\n", RAD2DEG(SI_O_SI / SI_O_SI_count) ); fflush( fout ); }
/* ASSUMPTION: Bond lists are sorted */ void Compare_Bonding( int atom, reax_system *system, control_params *control, static_storage *workspace, list *old_bonds, list *new_bonds, FILE *fout ) { int oldp, newp; /* fprintf( fout, "\n%d\nold_bonds:", atom ); for( oldp = Start_Index( atom, old_bonds ); oldp < End_Index( atom, old_bonds ); ++oldp ) if( old_bonds->select.bond_list[oldp].bo_data.BO >= control->bg_cut ) fprintf( fout, "%5d", old_bonds->select.bond_list[oldp].nbr ); fprintf( fout, "\nnew_bonds:" ); for( newp = Start_Index( atom, new_bonds ); newp < End_Index( atom, new_bonds ); ++newp ) if( new_bonds->select.bond_list[newp].bo_data.BO >= control->bg_cut ) fprintf( fout, "%6d", new_bonds->select.bond_list[newp].nbr ); fprintf( fout, "\n" ); */ for( oldp = Start_Index( atom, old_bonds ); oldp < End_Index( atom, old_bonds ) && old_bonds->select.bond_list[oldp].nbr < atom; ++oldp ); for( newp = Start_Index( atom, new_bonds ); newp < End_Index( atom, new_bonds ) && new_bonds->select.bond_list[newp].nbr < atom; ++newp ); while( oldp < End_Index( atom, old_bonds ) || newp < End_Index( atom, new_bonds ) ) { while( oldp < End_Index( atom, old_bonds ) && old_bonds->select.bond_list[oldp].bo_data.BO < control->bg_cut ) ++oldp; while( newp < End_Index( atom, new_bonds ) && new_bonds->select.bond_list[newp].bo_data.BO < control->bg_cut ) ++newp; /*fprintf( fout, "%d, oldp: %d - %d: %f newp: %d - %d: %f", atom, oldp, old_bonds->select.bond_list[oldp].nbr, old_bonds->select.bond_list[oldp].bo_data.BO, newp, new_bonds->select.bond_list[newp].nbr, new_bonds->select.bond_list[newp].bo_data.BO ); */ if( oldp < End_Index( atom, old_bonds ) ) { /* there are some more bonds in the old list */ if( newp < End_Index( atom, new_bonds ) ) { if( old_bonds->select.bond_list[oldp].nbr < new_bonds->select.bond_list[newp].nbr ) { // fprintf( fout, "%5d-%5d bond broken\n", // atom, old_bonds->select.bond_list[oldp].nbr ); Report_Bond_Change( system, control, workspace, old_bonds, new_bonds, atom, old_bonds->select.bond_list[oldp].nbr, 0, fout ); ++oldp; } else if( old_bonds->select.bond_list[oldp].nbr > new_bonds->select.bond_list[newp].nbr ) { // fprintf( fout, "%5d-%5d bond formed\n", // atom, new_bonds->select.bond_list[newp].nbr ); Report_Bond_Change( system, control, workspace, old_bonds, new_bonds, atom, new_bonds->select.bond_list[newp].nbr, 1, fout ); ++newp; } else ++newp, ++oldp; } else /* there is no other bond in the new list */ while( oldp < End_Index( atom, old_bonds ) ) { if( old_bonds->select.bond_list[oldp].bo_data.BO>=control->bg_cut ) { // fprintf( fout, "%5d-%5d bond broken\n", // atom, old_bonds->select.bond_list[oldp].nbr ); Report_Bond_Change( system, control, workspace, old_bonds, new_bonds, atom, old_bonds->select.bond_list[oldp].nbr, 0, fout ); } ++oldp; } } else { /* there are no more bonds in old_bond list */ if( newp < End_Index( atom, new_bonds ) ) /* there is at least one other bond in the new list */ while( newp < End_Index( atom, new_bonds ) ) { if( new_bonds->select.bond_list[newp].bo_data.BO>=control->bg_cut ){ // fprintf( fout, "%5d-%5d bond formed\n", // atom, new_bonds->select.bond_list[newp].nbr ); Report_Bond_Change( system, control, workspace, old_bonds, new_bonds, atom, new_bonds->select.bond_list[newp].nbr, 1, fout ); } ++newp; } else { /* there is no other bond in the new list, either -- no need to do anything */ } } } }
void Compute_Bond_Boost_Force_All_Couple(reax_system *system, control_params *control, simulation_data *data, static_storage *workspace, list **lists, output_controls *out_control) { int i, j, pj; int type_i, type_j; int adatom, adatom2; // label the boost atom int nbond, nrad; // Nb int start_i, end_i; real e, emax, r, re, r_max; // eta, eta_max, r, r_e real bo; real A, dA, V; // A(\eta^max), and \Delta A(\eta^max) real *rv, *rv_max; real q, P1, vmax; // q, P1 in equation 13 real S1, S2, f1, f2, C1, C2; real T; real bf, bfactor; // boost force scale rvec df; // boost force reax_atom *atom1, *atom2; bond_order_data *bo_ij; two_body_parameters *twbp; list *bonds; nrad = Find_Radicals(system, control, data, workspace, lists, out_control); //nrad = 0; //printf("-------------------------step %d -----------------\n", data->step); bonds = (*lists) + BONDS; // bond boost parameters q = control->bboost_q; // should read this from control file P1 = control->bboost_P1; vmax = control->bboost_Vmax; // initiate parameters e = 0; adatom = 0; adatom2 = 0; bo = 0.0; re = 0.001; A = 0.0; dA = 0.0; r_max = 0.0; bfactor = 1.0; T = control->T_final; V = 0.0; // bost energy nbond = 0; emax = 0.0; // first get the max bond order for( i=0; i < system->N; ++i ) { start_i = Start_Index(i, bonds); end_i = End_Index(i, bonds); for( pj = start_i; pj < end_i; ++pj ){ if( i < bonds->select.bond_list[pj].nbr ) { j = bonds->select.bond_list[pj].nbr; type_i = system->atoms[i].type; type_j = system->atoms[j].type; twbp = &( system->reaxprm.tbp[type_i][type_j] ); vmax = control->bboost_Vmax; vmax = twbp->v_max; bo_ij = &( bonds->select.bond_list[pj].bo_data ); re = twbp->r_e; // get r_e from ffield.ext r = bonds->select.bond_list[pj].d; e = (r - re)/re; // eta bo = bo_ij->BO; if (bo > q && vmax > 0) { nbond += 1; if ( fabs(emax) < fabs(e) ) { emax = e; adatom = i; adatom2 = j; /* for debug printf("i = %d, j = %d, re = %.2f, r = %.2f ", i, j, re, r); printf("x1 = %.2f, y1 = %.2f, z1 = %.2f, ", \ system->atoms[i].x[0], system->atoms[i].x[1], system->atoms[i].x[2]); printf("x2 = %.2f, y2 = %.2f, z2 = %.2f\n", \ system->atoms[j].x[0], system->atoms[j].x[1], system->atoms[j].x[2]); printf( " %4s %4s\n", \ system->reaxprm.sbp[ system->atoms[i].type ].name, system->reaxprm.sbp[ system->atoms[j].type ].name); */ rv_max = bonds->select.bond_list[pj].dvec; r_max = bonds->select.bond_list[pj].d;; } } } } } int ntmp; if (fabs(emax) < q && nbond > 0 && nrad <= control->bboost_nrad) { data->boost ++ ; // calculate A, and dA S1 = emax/q; S2 = S1 * S1; C1 = 1 - (emax/q)*(emax/q); C2 = 1 - P1*P1*S2; A = C1 * C1 / C2; ntmp = 0; for( i=0; i < system->N; ++i ) { start_i = Start_Index(i, bonds); end_i = End_Index(i, bonds); for( pj = start_i; pj < end_i; ++pj ) { if( i < bonds->select.bond_list[pj].nbr ) { j = bonds->select.bond_list[pj].nbr; type_i = system->atoms[i].type; type_j = system->atoms[j].type; twbp = &( system->reaxprm.tbp[type_i][type_j] ); vmax = control->bboost_Vmax; vmax = twbp->v_max; bo_ij = &( bonds->select.bond_list[pj].bo_data ); r = bonds->select.bond_list[pj].d; re = twbp->r_e; // get r_e from ffield.ext rv = bonds->select.bond_list[pj].dvec; bo = bo_ij->BO; if (bo > q && vmax > 0) { e = (r - re)/re; // eta C1 = 1 - e*e/(q*q); V += vmax / nbond * C1; bf = 2*A*vmax*e/(nbond*q*q*re); if (fabs(e - emax) < 0.00001) { C2 = 1 - e*e*P1*P1/(q*q); f1 = 2/(q*q*re); f2 = f1/2*P1*P1; dA = 2*e*C1/C2*(f1 - f2*C1/C2); } rvec_Scale(df, bf, rv); atom1 = &( system->atoms[i] ); atom2 = &( system->atoms[j] ); rvec_Add(system->atoms[i].f, df); rvec_ScaledAdd(system->atoms[j].f, -1, df); ntmp++; } } } } // add the contribution of evalope function A bf = dA * V; rvec_Scale(df, bf, rv_max); atom1 = &( system->atoms[adatom]); rvec_Add(system->atoms[adatom].f, df); rvec_ScaledAdd(system->atoms[adatom2].f, -1, df); } else { data->boost = 0; } bfactor = exp(4184 * A * V/(T * 8.314)); //bfactor = V; fprintf( out_control->bboost, "%-10d%6d%6d%6d%3d%8.4f%8.4f %44.4f", \ data->step, nbond, adatom, adatom2, nrad, r_max, emax, bfactor ); fprintf( out_control->bboost, " %4s %4s\n", \ system->reaxprm.sbp[ system->atoms[adatom].type ].name, system->reaxprm.sbp[ system->atoms[adatom2].type ].name); fflush( out_control->bboost); }
void Init_Forces( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, MPI_Comm comm ) { int i, j, pj; int start_i, end_i; int type_i, type_j; int Htop, btop_i, btop_j, num_bonds, num_hbonds; int ihb, jhb, ihb_top, jhb_top; int local, flag, renbr; real r_ij, cutoff; sparse_matrix *H; reax_list *far_nbrs, *bonds, *hbonds; single_body_parameters *sbp_i, *sbp_j; two_body_parameters *twbp; far_neighbor_data *nbr_pj; reax_atom *atom_i, *atom_j; far_nbrs = *lists + FAR_NBRS; bonds = *lists + BONDS; hbonds = *lists + HBONDS; for( i = 0; i < system->n; ++i ) workspace->bond_mark[i] = 0; for( i = system->n; i < system->N; ++i ) { workspace->bond_mark[i] = 1000; // put ghost atoms to an infinite distance //workspace->done_after[i] = Start_Index( i, far_nbrs ); } H = workspace->H; H->n = system->n; Htop = 0; num_bonds = 0; num_hbonds = 0; btop_i = btop_j = 0; renbr = (data->step-data->prev_steps) % control->reneighbor == 0; for( i = 0; i < system->N; ++i ) { atom_i = &(system->my_atoms[i]); type_i = atom_i->type; start_i = Start_Index(i, far_nbrs); end_i = End_Index(i, far_nbrs); btop_i = End_Index( i, bonds ); sbp_i = &(system->reax_param.sbp[type_i]); if( i < system->n ) { local = 1; cutoff = control->nonb_cut; } else { local = 0; cutoff = control->bond_cut; } ihb = -1; ihb_top = -1; if( local ) { H->start[i] = Htop; H->entries[Htop].j = i; H->entries[Htop].val = sbp_i->eta; ++Htop; if( control->hbond_cut > 0 ) { ihb = sbp_i->p_hbond; if( ihb == 1 ) ihb_top = End_Index( atom_i->Hindex, hbonds ); else ihb_top = -1; } } /* update i-j distance - check if j is within cutoff */ for( pj = start_i; pj < end_i; ++pj ) { nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); j = nbr_pj->nbr; atom_j = &(system->my_atoms[j]); //fprintf( stderr, "%d%d i=%d x_i: %f %f %f,j=%d x_j: %f %f %f, d=%f\n", // MIN(atom_i->orig_id, atom_j->orig_id), // MAX(atom_i->orig_id, atom_j->orig_id), // i, atom_i->x[0], atom_i->x[1], atom_i->x[2], // j, atom_j->x[0], atom_j->x[1], atom_j->x[2], nbr_pj->d ); if( renbr ) { if(nbr_pj->d <= cutoff) flag = 1; else flag = 0; } else{ nbr_pj->dvec[0] = atom_j->x[0] - atom_i->x[0]; nbr_pj->dvec[1] = atom_j->x[1] - atom_i->x[1]; nbr_pj->dvec[2] = atom_j->x[2] - atom_i->x[2]; nbr_pj->d = rvec_Norm_Sqr( nbr_pj->dvec ); if( nbr_pj->d <= SQR(cutoff) ) { nbr_pj->d = sqrt(nbr_pj->d); flag = 1; } else { flag = 0; } } if( flag ){ type_j = atom_j->type; r_ij = nbr_pj->d; sbp_j = &(system->reax_param.sbp[type_j]); twbp = &(system->reax_param.tbp[type_i][type_j]); if( local ) { /* H matrix entry */ if( j < system->n || atom_i->orig_id < atom_j->orig_id ) {//tryQEq||1 H->entries[Htop].j = j; //fprintf( stdout, "%d%d %d %d\n", // MIN(atom_i->orig_id, atom_j->orig_id), // MAX(atom_i->orig_id, atom_j->orig_id), // MIN(atom_i->orig_id, atom_j->orig_id), // MAX(atom_i->orig_id, atom_j->orig_id) ); if( control->tabulate == 0 ) H->entries[Htop].val = Compute_H(r_ij,twbp->gamma,workspace->Tap); else H->entries[Htop].val = Compute_tabH(r_ij, type_i, type_j); ++Htop; } /* hydrogen bond lists */ if( control->hbond_cut > 0 && (ihb==1 || ihb==2) && nbr_pj->d <= control->hbond_cut ) { // fprintf( stderr, "%d %d\n", atom1, atom2 ); jhb = sbp_j->p_hbond; if( ihb == 1 && jhb == 2 ) { hbonds->select.hbond_list[ihb_top].nbr = j; hbonds->select.hbond_list[ihb_top].scl = 1; hbonds->select.hbond_list[ihb_top].ptr = nbr_pj; ++ihb_top; ++num_hbonds; } else if( j < system->n && ihb == 2 && jhb == 1 ) { jhb_top = End_Index( atom_j->Hindex, hbonds ); hbonds->select.hbond_list[jhb_top].nbr = i; hbonds->select.hbond_list[jhb_top].scl = -1; hbonds->select.hbond_list[jhb_top].ptr = nbr_pj; Set_End_Index( atom_j->Hindex, jhb_top+1, hbonds ); ++num_hbonds; } } } /* uncorrected bond orders */ if( //(workspace->bond_mark[i] < 3 || workspace->bond_mark[j] < 3) && nbr_pj->d <= control->bond_cut && BOp( workspace, bonds, control->bo_cut, i , btop_i, nbr_pj, sbp_i, sbp_j, twbp ) ) { num_bonds += 2; ++btop_i; if( workspace->bond_mark[j] > workspace->bond_mark[i] + 1 ) workspace->bond_mark[j] = workspace->bond_mark[i] + 1; else if( workspace->bond_mark[i] > workspace->bond_mark[j] + 1 ) { workspace->bond_mark[i] = workspace->bond_mark[j] + 1; //if( workspace->bond_mark[i] == 1000 ) // workspace->done_after[i] = pj; } //fprintf( stdout, "%d%d - %d(%d) %d(%d)\n", // i , j, i, workspace->bond_mark[i], j, workspace->bond_mark[j] ); } } } Set_End_Index( i, btop_i, bonds ); if( local ) { H->end[i] = Htop; if( ihb == 1 ) Set_End_Index( atom_i->Hindex, ihb_top, hbonds ); } } //fprintf( stderr, "after the first init loop\n" ); /*for( i = system->n; i < system->N; ++i ) if( workspace->bond_mark[i] > 3 ) { start_i = Start_Index(i, bonds); end_i = End_Index(i, bonds); num_bonds -= (end_i - start_i); Set_End_Index(i, start_i, bonds ); }*/ /*for( i = system->n; i < system->N; ++i ) { start_i = Start_Index(i, far_nbrs); end_i = workspace->done_after[i]; if( workspace->bond_mark[i] >= 2 && start_i < end_i ) { atom_i = &(system->my_atoms[i]); type_i = atom_i->type; btop_i = End_Index( i, bonds ); sbp_i = &(system->reax_param.sbp[type_i]); for( pj = start_i; pj < end_i; ++pj ) { nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); j = nbr_pj->nbr; if( workspace->bond_mark[j] >= 2 && nbr_pj->d <= control->bond_cut ) { atom_j = &(system->my_atoms[j]); type_j = atom_j->type; sbp_j = &(system->reax_param.sbp[type_j]); twbp = &(system->reax_param.tbp[type_i][type_j]); if( BOp( workspace, bonds, control->bo_cut, i , btop_i, nbr_pj, sbp_i, sbp_j, twbp ) ) { num_bonds += 2; ++btop_i; if( workspace->bond_mark[j] > workspace->bond_mark[i] + 1 ) workspace->bond_mark[j] = workspace->bond_mark[i] + 1; else if( workspace->bond_mark[i] > workspace->bond_mark[j] + 1 ) workspace->bond_mark[i] = workspace->bond_mark[j] + 1; //fprintf( stdout, "%d%d - %d(%d) %d(%d) new\n", // i , j, i, workspace->bond_mark[i], j, workspace->bond_mark[j] ); } } } Set_End_Index( i, btop_i, bonds ); } }*/ workspace->realloc.Htop = Htop; workspace->realloc.num_bonds = num_bonds; workspace->realloc.num_hbonds = num_hbonds; #if defined(DEBUG_FOCUS) fprintf( stderr, "p%d @ step%d: Htop = %d num_bonds = %d num_hbonds = %d\n", system->my_rank, data->step, Htop, num_bonds, num_hbonds ); MPI_Barrier( comm ); #endif #if defined( DEBUG ) Print_Bonds( system, bonds, "debugbonds.out" ); Print_Bond_List2( system, bonds, "pbonds.out" ); Print_Sparse_Matrix( system, H ); for( i = 0; i < H->n; ++i ) for( j = H->start[i]; j < H->end[i]; ++j ) fprintf( stderr, "%d %d %.15e\n", MIN(system->my_atoms[i].orig_id, system->my_atoms[H->entries[j].j].orig_id), MAX(system->my_atoms[i].orig_id, system->my_atoms[H->entries[j].j].orig_id), H->entries[j].val ); #endif Validate_Lists( system, workspace, lists, data->step, system->n, system->N, system->numH, comm ); }
void Init_Forces(reax_system *system, control_params *control, simulation_data *data, static_storage *workspace, list **lists, output_controls *out_control) { int i, j, pj; int start_i, end_i; int type_i, type_j; int Htop, btop_i, btop_j, num_bonds, num_hbonds; int ihb, jhb, ihb_top, jhb_top; int flag; real r_ij, r2, self_coef; real dr3gamij_1, dr3gamij_3, Tap; //real val, dif, base; real C12, C34, C56; real Cln_BOp_s, Cln_BOp_pi, Cln_BOp_pi2; real BO, BO_s, BO_pi, BO_pi2; real p_boc1, p_boc2; sparse_matrix *H; list *far_nbrs, *bonds, *hbonds; single_body_parameters *sbp_i, *sbp_j; two_body_parameters *twbp; far_neighbor_data *nbr_pj; //LR_lookup_table *t; reax_atom *atom_i, *atom_j; bond_data *ibond, *jbond; bond_order_data *bo_ij, *bo_ji; far_nbrs = *lists + FAR_NBRS; bonds = *lists + BONDS; hbonds = *lists + HBONDS; H = workspace->H; Htop = 0; num_bonds = 0; num_hbonds = 0; btop_i = btop_j = 0; p_boc1 = system->reaxprm.gp.l[0]; p_boc2 = system->reaxprm.gp.l[1]; for (i = 0; i < system->N; ++i) { atom_i = &(system->atoms[i]); type_i = atom_i->type; start_i = Start_Index(i, far_nbrs); end_i = End_Index(i, far_nbrs); H->start[i] = Htop; btop_i = End_Index(i, bonds); sbp_i = &(system->reaxprm.sbp[type_i]); ihb = ihb_top = -1; if (control->hb_cut > 0 && (ihb = sbp_i->p_hbond) == 1) ihb_top = End_Index(workspace->hbond_index[i], hbonds); for (pj = start_i; pj < end_i; ++pj) { nbr_pj = &(far_nbrs->select.far_nbr_list[pj]); j = nbr_pj->nbr; atom_j = &(system->atoms[j]); flag = 0; if ((data->step - data->prev_steps) % control->reneighbor == 0) { if (nbr_pj->d <= control->r_cut) flag = 1; else flag = 0; } else if ((nbr_pj->d = Sq_Distance_on_T3(atom_i->x, atom_j->x, &(system->box), nbr_pj->dvec)) <= SQR(control->r_cut)) { nbr_pj->d = sqrt(nbr_pj->d); flag = 1; } if (flag) { type_j = system->atoms[j].type; r_ij = nbr_pj->d; sbp_j = &(system->reaxprm.sbp[type_j]); twbp = &(system->reaxprm.tbp[type_i][type_j]); self_coef = (i == j) ? 0.5 : 1.0; /* H matrix entry */ Tap = control->Tap7 * r_ij + control->Tap6; Tap = Tap * r_ij + control->Tap5; Tap = Tap * r_ij + control->Tap4; Tap = Tap * r_ij + control->Tap3; Tap = Tap * r_ij + control->Tap2; Tap = Tap * r_ij + control->Tap1; Tap = Tap * r_ij + control->Tap0; dr3gamij_1 = (r_ij * r_ij * r_ij + twbp->gamma); dr3gamij_3 = POW(dr3gamij_1, 0.33333333333333); H->entries[Htop].j = j; H->entries[Htop].val = self_coef * Tap * EV_to_KCALpMOL / dr3gamij_3; ++Htop; /* hydrogen bond lists */ if (control->hb_cut > 0 && (ihb == 1 || ihb == 2) && nbr_pj->d <= control->hb_cut) { // fprintf( stderr, "%d %d\n", atom1, atom2 ); jhb = sbp_j->p_hbond; if (ihb == 1 && jhb == 2) { hbonds->select.hbond_list[ihb_top].nbr = j; hbonds->select.hbond_list[ihb_top].scl = 1; hbonds->select.hbond_list[ihb_top].ptr = nbr_pj; ++ihb_top; ++num_hbonds; } else if (ihb == 2 && jhb == 1) { jhb_top = End_Index(workspace->hbond_index[j], hbonds); hbonds->select.hbond_list[jhb_top].nbr = i; hbonds->select.hbond_list[jhb_top].scl = -1; hbonds->select.hbond_list[jhb_top].ptr = nbr_pj; Set_End_Index(workspace->hbond_index[j], jhb_top + 1, hbonds); ++num_hbonds; } } /* uncorrected bond orders */ if (far_nbrs->select.far_nbr_list[pj].d <= control->nbr_cut) { r2 = SQR(r_ij); if (sbp_i->r_s > 0.0 && sbp_j->r_s > 0.0) { C12 = twbp->p_bo1 * POW(r_ij / twbp->r_s, twbp->p_bo2); BO_s = (1.0 + control->bo_cut) * EXP(C12); } else BO_s = C12 = 0.0; if (sbp_i->r_pi > 0.0 && sbp_j->r_pi > 0.0) { C34 = twbp->p_bo3 * POW(r_ij / twbp->r_p, twbp->p_bo4); BO_pi = EXP(C34); } else BO_pi = C34 = 0.0; if (sbp_i->r_pi_pi > 0.0 && sbp_j->r_pi_pi > 0.0) { C56 = twbp->p_bo5 * POW(r_ij / twbp->r_pp, twbp->p_bo6); BO_pi2 = EXP(C56); } else BO_pi2 = C56 = 0.0; /* Initially BO values are the uncorrected ones, page 1 */ BO = BO_s + BO_pi + BO_pi2; if (BO >= control->bo_cut) { num_bonds += 2; /****** bonds i-j and j-i ******/ ibond = &(bonds->select.bond_list[btop_i]); btop_j = End_Index(j, bonds); jbond = &(bonds->select.bond_list[btop_j]); ibond->nbr = j; jbond->nbr = i; ibond->d = r_ij; jbond->d = r_ij; rvec_Copy(ibond->dvec, nbr_pj->dvec); rvec_Scale(jbond->dvec, -1, nbr_pj->dvec); ivec_Copy(ibond->rel_box, nbr_pj->rel_box); ivec_Scale(jbond->rel_box, -1, nbr_pj->rel_box); ibond->dbond_index = btop_i; jbond->dbond_index = btop_i; ibond->sym_index = btop_j; jbond->sym_index = btop_i; ++btop_i; Set_End_Index(j, btop_j + 1, bonds); bo_ij = &(ibond->bo_data); bo_ji = &(jbond->bo_data); bo_ji->BO = bo_ij->BO = BO; bo_ji->BO_s = bo_ij->BO_s = BO_s; bo_ji->BO_pi = bo_ij->BO_pi = BO_pi; bo_ji->BO_pi2 = bo_ij->BO_pi2 = BO_pi2; /* Bond Order page2-3, derivative of total bond order prime */ Cln_BOp_s = twbp->p_bo2 * C12 / r2; Cln_BOp_pi = twbp->p_bo4 * C34 / r2; Cln_BOp_pi2 = twbp->p_bo6 * C56 / r2; /* Only dln_BOp_xx wrt. dr_i is stored here, note that dln_BOp_xx/dr_i = -dln_BOp_xx/dr_j and all others are 0 */ rvec_Scale(bo_ij->dln_BOp_s, -bo_ij->BO_s * Cln_BOp_s, ibond->dvec); rvec_Scale(bo_ij->dln_BOp_pi, -bo_ij->BO_pi * Cln_BOp_pi, ibond->dvec); rvec_Scale(bo_ij->dln_BOp_pi2, -bo_ij->BO_pi2 * Cln_BOp_pi2, ibond->dvec); rvec_Scale(bo_ji->dln_BOp_s, -1., bo_ij->dln_BOp_s); rvec_Scale(bo_ji->dln_BOp_pi, -1., bo_ij->dln_BOp_pi); rvec_Scale(bo_ji->dln_BOp_pi2, -1., bo_ij->dln_BOp_pi2); /* Only dBOp wrt. dr_i is stored here, note that dBOp/dr_i = -dBOp/dr_j and all others are 0 */ rvec_Scale(bo_ij->dBOp, -(bo_ij->BO_s * Cln_BOp_s + bo_ij->BO_pi * Cln_BOp_pi + bo_ij->BO_pi2 * Cln_BOp_pi2), ibond->dvec); rvec_Scale(bo_ji->dBOp, -1., bo_ij->dBOp); rvec_Add(workspace->dDeltap_self[i], bo_ij->dBOp); rvec_Add(workspace->dDeltap_self[j], bo_ji->dBOp); bo_ij->BO_s -= control->bo_cut; bo_ij->BO -= control->bo_cut; bo_ji->BO_s -= control->bo_cut; bo_ji->BO -= control->bo_cut; workspace->total_bond_order[i] += bo_ij->BO; //currently total_BOp workspace->total_bond_order[j] += bo_ji->BO; //currently total_BOp bo_ij->Cdbo = bo_ij->Cdbopi = bo_ij->Cdbopi2 = 0.0; bo_ji->Cdbo = bo_ji->Cdbopi = bo_ji->Cdbopi2 = 0.0; /*fprintf( stderr, "%d %d %g %g %g\n", i+1, j+1, bo_ij->BO, bo_ij->BO_pi, bo_ij->BO_pi2 );*/ /*fprintf( stderr, "Cln_BOp_s: %f, pbo2: %f, C12:%f\n", Cln_BOp_s, twbp->p_bo2, C12 ); fprintf( stderr, "Cln_BOp_pi: %f, pbo4: %f, C34:%f\n", Cln_BOp_pi, twbp->p_bo4, C34 ); fprintf( stderr, "Cln_BOp_pi2: %f, pbo6: %f, C56:%f\n", Cln_BOp_pi2, twbp->p_bo6, C56 );*/ /*fprintf(stderr, "pbo1: %f, pbo2:%f\n", twbp->p_bo1, twbp->p_bo2); fprintf(stderr, "pbo3: %f, pbo4:%f\n", twbp->p_bo3, twbp->p_bo4); fprintf(stderr, "pbo5: %f, pbo6:%f\n", twbp->p_bo5, twbp->p_bo6); fprintf( stderr, "r_s: %f, r_p: %f, r_pp: %f\n", twbp->r_s, twbp->r_p, twbp->r_pp ); fprintf( stderr, "C12: %g, C34:%g, C56:%g\n", C12, C34, C56 );*/ /*fprintf( stderr, "\tfactors: %g %g %g\n", -(bo_ij->BO_s * Cln_BOp_s + bo_ij->BO_pi * Cln_BOp_pi + bo_ij->BO_pi2 * Cln_BOp_pp), -bo_ij->BO_pi * Cln_BOp_pi, -bo_ij->BO_pi2 * Cln_BOp_pi2 );*/ /*fprintf( stderr, "dBOpi:\t[%g, %g, %g]\n", bo_ij->dBOp[0], bo_ij->dBOp[1], bo_ij->dBOp[2] ); fprintf( stderr, "dBOpi:\t[%g, %g, %g]\n", bo_ij->dln_BOp_pi[0], bo_ij->dln_BOp_pi[1], bo_ij->dln_BOp_pi[2] ); fprintf( stderr, "dBOpi2:\t[%g, %g, %g]\n\n", bo_ij->dln_BOp_pi2[0], bo_ij->dln_BOp_pi2[1], bo_ij->dln_BOp_pi2[2] );*/ Set_End_Index(j, btop_j + 1, bonds); } } } } H->entries[Htop].j = i; H->entries[Htop].val = system->reaxprm.sbp[type_i].eta; ++Htop; Set_End_Index(i, btop_i, bonds); if (ihb == 1) Set_End_Index(workspace->hbond_index[i], ihb_top, hbonds); //fprintf( stderr, "%d bonds start: %d, end: %d\n", // i, Start_Index( i, bonds ), End_Index( i, bonds ) ); } // mark the end of j list H->start[i] = Htop; /* validate lists - decide if reallocation is required! */ Validate_Lists(workspace, lists, data->step, system->N, H->m, Htop, num_bonds, num_hbonds); #if defined(DEBUG_FOCUS) fprintf( stderr, "step%d: Htop = %d, num_bonds = %d, num_hbonds = %d\n", data->step, Htop, num_bonds, num_hbonds ); #endif }
void Atom_Energy( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control ) { int i, j, pj, type_i, type_j; real Delta_lpcorr, dfvl; real e_lp, expvd2, inv_expvd2, dElp, CElp, DlpVi; real e_lph, Di, vov3, deahu2dbo, deahu2dsbo; real e_ov, CEover1, CEover2, CEover3, CEover4; real exp_ovun1, exp_ovun2, sum_ovun1, sum_ovun2; real exp_ovun2n, exp_ovun6, exp_ovun8; real inv_exp_ovun1, inv_exp_ovun2, inv_exp_ovun2n, inv_exp_ovun8; real e_un, CEunder1, CEunder2, CEunder3, CEunder4; real p_lp2, p_lp3; real p_ovun2, p_ovun3, p_ovun4, p_ovun5, p_ovun6, p_ovun7, p_ovun8; real eng_tmp; int numbonds; single_body_parameters *sbp_i; two_body_parameters *twbp; bond_data *pbond; bond_order_data *bo_ij; reax_list *bonds = (*lists) + BONDS; /* Initialize parameters */ p_lp3 = system->reax_param.gp.l[5]; p_ovun3 = system->reax_param.gp.l[32]; p_ovun4 = system->reax_param.gp.l[31]; p_ovun6 = system->reax_param.gp.l[6]; p_ovun7 = system->reax_param.gp.l[8]; p_ovun8 = system->reax_param.gp.l[9]; for( i = 0; i < system->n; ++i ) { /* set the parameter pointer */ type_i = system->my_atoms[i].type; if (type_i < 0) continue; sbp_i = &(system->reax_param.sbp[ type_i ]); /* lone-pair Energy */ p_lp2 = sbp_i->p_lp2; expvd2 = exp( -75 * workspace->Delta_lp[i] ); inv_expvd2 = 1. / (1. + expvd2 ); numbonds = 0; e_lp = 0.0; for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) numbonds ++; /* calculate the energy */ if (numbonds > 0) data->my_en.e_lp += e_lp = p_lp2 * workspace->Delta_lp[i] * inv_expvd2; dElp = p_lp2 * inv_expvd2 + 75 * p_lp2 * workspace->Delta_lp[i] * expvd2 * SQR(inv_expvd2); CElp = dElp * workspace->dDelta_lp[i]; if (numbonds > 0) workspace->CdDelta[i] += CElp; // lp - 1st term /* tally into per-atom energy */ if( system->pair_ptr->evflag) system->pair_ptr->ev_tally(i,i,system->n,1,e_lp,0.0,0.0,0.0,0.0,0.0); /* correction for C2 */ if( p_lp3 > 0.001 && !strcmp(system->reax_param.sbp[type_i].name, "C") ) for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) { j = bonds->select.bond_list[pj].nbr; type_j = system->my_atoms[j].type; if (type_j < 0) continue; if( !strcmp( system->reax_param.sbp[type_j].name, "C" ) ) { twbp = &( system->reax_param.tbp[type_i][type_j]); bo_ij = &( bonds->select.bond_list[pj].bo_data ); Di = workspace->Delta[i]; vov3 = bo_ij->BO - Di - 0.040*pow(Di, 4.); if( vov3 > 3. ) { data->my_en.e_lp += e_lph = p_lp3 * SQR(vov3-3.0); deahu2dbo = 2.*p_lp3*(vov3 - 3.); deahu2dsbo = 2.*p_lp3*(vov3 - 3.)*(-1. - 0.16*pow(Di, 3.)); bo_ij->Cdbo += deahu2dbo; workspace->CdDelta[i] += deahu2dsbo; /* tally into per-atom energy */ if( system->pair_ptr->evflag) system->pair_ptr->ev_tally(i,j,system->n,1,e_lph,0.0,0.0,0.0,0.0,0.0); } } } } for( i = 0; i < system->n; ++i ) { type_i = system->my_atoms[i].type; if (type_i < 0) continue; sbp_i = &(system->reax_param.sbp[ type_i ]); /* over-coordination energy */ if( sbp_i->mass > 21.0 ) dfvl = 0.0; else dfvl = 1.0; // only for 1st-row elements p_ovun2 = sbp_i->p_ovun2; sum_ovun1 = sum_ovun2 = 0; for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) { j = bonds->select.bond_list[pj].nbr; type_j = system->my_atoms[j].type; if (type_j < 0) continue; bo_ij = &(bonds->select.bond_list[pj].bo_data); twbp = &(system->reax_param.tbp[ type_i ][ type_j ]); sum_ovun1 += twbp->p_ovun1 * twbp->De_s * bo_ij->BO; sum_ovun2 += (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j])* ( bo_ij->BO_pi + bo_ij->BO_pi2 ); } exp_ovun1 = p_ovun3 * exp( p_ovun4 * sum_ovun2 ); inv_exp_ovun1 = 1.0 / (1 + exp_ovun1); Delta_lpcorr = workspace->Delta[i] - (dfvl * workspace->Delta_lp_temp[i]) * inv_exp_ovun1; exp_ovun2 = exp( p_ovun2 * Delta_lpcorr ); inv_exp_ovun2 = 1.0 / (1.0 + exp_ovun2); DlpVi = 1.0 / (Delta_lpcorr + sbp_i->valency + 1e-8); CEover1 = Delta_lpcorr * DlpVi * inv_exp_ovun2; data->my_en.e_ov += e_ov = sum_ovun1 * CEover1; CEover2 = sum_ovun1 * DlpVi * inv_exp_ovun2 * (1.0 - Delta_lpcorr * ( DlpVi + p_ovun2 * exp_ovun2 * inv_exp_ovun2 )); CEover3 = CEover2 * (1.0 - dfvl * workspace->dDelta_lp[i] * inv_exp_ovun1 ); CEover4 = CEover2 * (dfvl * workspace->Delta_lp_temp[i]) * p_ovun4 * exp_ovun1 * SQR(inv_exp_ovun1); /* under-coordination potential */ p_ovun2 = sbp_i->p_ovun2; p_ovun5 = sbp_i->p_ovun5; exp_ovun2n = 1.0 / exp_ovun2; exp_ovun6 = exp( p_ovun6 * Delta_lpcorr ); exp_ovun8 = p_ovun7 * exp(p_ovun8 * sum_ovun2); inv_exp_ovun2n = 1.0 / (1.0 + exp_ovun2n); inv_exp_ovun8 = 1.0 / (1.0 + exp_ovun8); numbonds = 0; e_un = 0.0; for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) numbonds ++; if (numbonds > 0) data->my_en.e_un += e_un = -p_ovun5 * (1.0 - exp_ovun6) * inv_exp_ovun2n * inv_exp_ovun8; CEunder1 = inv_exp_ovun2n * ( p_ovun5 * p_ovun6 * exp_ovun6 * inv_exp_ovun8 + p_ovun2 * e_un * exp_ovun2n ); CEunder2 = -e_un * p_ovun8 * exp_ovun8 * inv_exp_ovun8; CEunder3 = CEunder1 * (1.0 - dfvl*workspace->dDelta_lp[i]*inv_exp_ovun1); CEunder4 = CEunder1 * (dfvl*workspace->Delta_lp_temp[i]) * p_ovun4 * exp_ovun1 * SQR(inv_exp_ovun1) + CEunder2; /* tally into per-atom energy */ if( system->pair_ptr->evflag) { eng_tmp = e_ov; if (numbonds > 0) eng_tmp += e_un; system->pair_ptr->ev_tally(i,i,system->n,1,eng_tmp,0.0,0.0,0.0,0.0,0.0); } /* forces */ workspace->CdDelta[i] += CEover3; // OvCoor - 2nd term if (numbonds > 0) workspace->CdDelta[i] += CEunder3; // UnCoor - 1st term for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) { pbond = &(bonds->select.bond_list[pj]); j = pbond->nbr; bo_ij = &(pbond->bo_data); twbp = &(system->reax_param.tbp[ system->my_atoms[i].type ] [system->my_atoms[pbond->nbr].type]); bo_ij->Cdbo += CEover1 * twbp->p_ovun1 * twbp->De_s;// OvCoor-1st workspace->CdDelta[j] += CEover4 * (1.0 - dfvl*workspace->dDelta_lp[j]) * (bo_ij->BO_pi + bo_ij->BO_pi2); // OvCoor-3a bo_ij->Cdbopi += CEover4 * (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]); // OvCoor-3b bo_ij->Cdbopi2 += CEover4 * (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]); // OvCoor-3b workspace->CdDelta[j] += CEunder4 * (1.0 - dfvl*workspace->dDelta_lp[j]) * (bo_ij->BO_pi + bo_ij->BO_pi2); // UnCoor - 2a bo_ij->Cdbopi += CEunder4 * (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]); // UnCoor-2b bo_ij->Cdbopi2 += CEunder4 * (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]); // UnCoor-2b } } }
void Tabulated_vdW_Coulomb_Energy( reax_system *system,control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control ) { int i, j, pj, r, natoms; int type_i, type_j, tmin, tmax; int start_i, end_i, flag; rc_tagint orig_i, orig_j; double r_ij, base, dif; double e_vdW, e_ele; double CEvd, CEclmb, SMALL = 0.0001; double f_tmp, delij[3]; rvec temp, ext_press; far_neighbor_data *nbr_pj; reax_list *far_nbrs; LR_lookup_table *t; natoms = system->n; far_nbrs = (*lists) + FAR_NBRS; e_ele = e_vdW = 0; for( i = 0; i < natoms; ++i ) { type_i = system->my_atoms[i].type; if (type_i < 0) continue; start_i = Start_Index(i,far_nbrs); end_i = End_Index(i,far_nbrs); orig_i = system->my_atoms[i].orig_id; for( pj = start_i; pj < end_i; ++pj ) { nbr_pj = &(far_nbrs->select.far_nbr_list[pj]); j = nbr_pj->nbr; type_j = system->my_atoms[j].type; if (type_j < 0) continue; orig_j = system->my_atoms[j].orig_id; flag = 0; if(nbr_pj->d <= control->nonb_cut) { if (j < natoms) flag = 1; else if (orig_i < orig_j) flag = 1; else if (orig_i == orig_j) { if (nbr_pj->dvec[2] > SMALL) flag = 1; else if (fabs(nbr_pj->dvec[2]) < SMALL) { if (nbr_pj->dvec[1] > SMALL) flag = 1; else if (fabs(nbr_pj->dvec[1]) < SMALL && nbr_pj->dvec[0] > SMALL) flag = 1; } } } if (flag) { r_ij = nbr_pj->d; tmin = MIN( type_i, type_j ); tmax = MAX( type_i, type_j ); t = &( LR[tmin][tmax] ); /* Cubic Spline Interpolation */ r = (int)(r_ij * t->inv_dx); if( r == 0 ) ++r; base = (double)(r+1) * t->dx; dif = r_ij - base; e_vdW = ((t->vdW[r].d*dif + t->vdW[r].c)*dif + t->vdW[r].b)*dif + t->vdW[r].a; e_ele = ((t->ele[r].d*dif + t->ele[r].c)*dif + t->ele[r].b)*dif + t->ele[r].a; e_ele *= system->my_atoms[i].q * system->my_atoms[j].q; data->my_en.e_vdW += e_vdW; data->my_en.e_ele += e_ele; CEvd = ((t->CEvd[r].d*dif + t->CEvd[r].c)*dif + t->CEvd[r].b)*dif + t->CEvd[r].a; CEclmb = ((t->CEclmb[r].d*dif+t->CEclmb[r].c)*dif+t->CEclmb[r].b)*dif + t->CEclmb[r].a; CEclmb *= system->my_atoms[i].q * system->my_atoms[j].q; /* tally into per-atom energy */ if( system->pair_ptr->evflag || system->pair_ptr->vflag_atom) { rvec_ScaledSum( delij, 1., system->my_atoms[i].x, -1., system->my_atoms[j].x ); f_tmp = -(CEvd + CEclmb); system->pair_ptr->ev_tally(i,j,natoms,1,e_vdW,e_ele, f_tmp,delij[0],delij[1],delij[2]); } if( control->virial == 0 ) { rvec_ScaledAdd( workspace->f[i], -(CEvd + CEclmb), nbr_pj->dvec ); rvec_ScaledAdd( workspace->f[j], +(CEvd + CEclmb), nbr_pj->dvec ); } else { // NPT, iNPT or sNPT rvec_Scale( temp, CEvd + CEclmb, nbr_pj->dvec ); rvec_ScaledAdd( workspace->f[i], -1., temp ); rvec_Add( workspace->f[j], temp ); rvec_iMultiply( ext_press, nbr_pj->rel_box, temp ); rvec_Add( data->my_ext_press, ext_press ); } } } } Compute_Polarization_Energy( system, data ); }
void Init_Forces_noQEq( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, MPI_Comm comm ) { int i, j, pj; int start_i, end_i; int type_i, type_j; int btop_i, btop_j, num_bonds, num_hbonds; int ihb, jhb, ihb_top, jhb_top; int local, flag, renbr; double cutoff; reax_list *far_nbrs, *bonds, *hbonds; single_body_parameters *sbp_i, *sbp_j; two_body_parameters *twbp; far_neighbor_data *nbr_pj; reax_atom *atom_i, *atom_j; far_nbrs = *lists + FAR_NBRS; bonds = *lists + BONDS; hbonds = *lists + HBONDS; for( i = 0; i < system->n; ++i ) workspace->bond_mark[i] = 0; for( i = system->n; i < system->N; ++i ) { workspace->bond_mark[i] = 1000; // put ghost atoms to an infinite distance } num_bonds = 0; num_hbonds = 0; btop_i = btop_j = 0; renbr = (data->step-data->prev_steps) % control->reneighbor == 0; for( i = 0; i < system->N; ++i ) { atom_i = &(system->my_atoms[i]); type_i = atom_i->type; if (type_i < 0) continue; start_i = Start_Index(i, far_nbrs); end_i = End_Index(i, far_nbrs); btop_i = End_Index( i, bonds ); sbp_i = &(system->reax_param.sbp[type_i]); if( i < system->n ) { local = 1; cutoff = MAX( control->hbond_cut, control->bond_cut ); } else { local = 0; cutoff = control->bond_cut; } ihb = -1; ihb_top = -1; if( local && control->hbond_cut > 0 ) { ihb = sbp_i->p_hbond; if( ihb == 1 ) ihb_top = End_Index( atom_i->Hindex, hbonds ); else ihb_top = -1; } /* update i-j distance - check if j is within cutoff */ for( pj = start_i; pj < end_i; ++pj ) { nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); j = nbr_pj->nbr; atom_j = &(system->my_atoms[j]); if( renbr ) { if( nbr_pj->d <= cutoff ) flag = 1; else flag = 0; } else{ nbr_pj->dvec[0] = atom_j->x[0] - atom_i->x[0]; nbr_pj->dvec[1] = atom_j->x[1] - atom_i->x[1]; nbr_pj->dvec[2] = atom_j->x[2] - atom_i->x[2]; nbr_pj->d = rvec_Norm_Sqr( nbr_pj->dvec ); if( nbr_pj->d <= SQR(cutoff) ) { nbr_pj->d = sqrt(nbr_pj->d); flag = 1; } else { flag = 0; } } if( flag ) { type_j = atom_j->type; if (type_j < 0) continue; sbp_j = &(system->reax_param.sbp[type_j]); twbp = &(system->reax_param.tbp[type_i][type_j]); if( local ) { /* hydrogen bond lists */ if( control->hbond_cut > 0 && (ihb==1 || ihb==2) && nbr_pj->d <= control->hbond_cut ) { // fprintf( stderr, "%d %d\n", atom1, atom2 ); jhb = sbp_j->p_hbond; if( ihb == 1 && jhb == 2 ) { hbonds->select.hbond_list[ihb_top].nbr = j; hbonds->select.hbond_list[ihb_top].scl = 1; hbonds->select.hbond_list[ihb_top].ptr = nbr_pj; ++ihb_top; ++num_hbonds; } else if( j < system->n && ihb == 2 && jhb == 1 ) { jhb_top = End_Index( atom_j->Hindex, hbonds ); hbonds->select.hbond_list[jhb_top].nbr = i; hbonds->select.hbond_list[jhb_top].scl = -1; hbonds->select.hbond_list[jhb_top].ptr = nbr_pj; Set_End_Index( atom_j->Hindex, jhb_top+1, hbonds ); ++num_hbonds; } } } if( //(workspace->bond_mark[i] < 3 || workspace->bond_mark[j] < 3) && nbr_pj->d <= control->bond_cut && BOp( workspace, bonds, control->bo_cut, i , btop_i, nbr_pj, sbp_i, sbp_j, twbp ) ) { num_bonds += 2; ++btop_i; if( workspace->bond_mark[j] > workspace->bond_mark[i] + 1 ) workspace->bond_mark[j] = workspace->bond_mark[i] + 1; else if( workspace->bond_mark[i] > workspace->bond_mark[j] + 1 ) { workspace->bond_mark[i] = workspace->bond_mark[j] + 1; } } } } Set_End_Index( i, btop_i, bonds ); if( local && ihb == 1 ) Set_End_Index( atom_i->Hindex, ihb_top, hbonds ); } workspace->realloc.num_bonds = num_bonds; workspace->realloc.num_hbonds = num_hbonds; Validate_Lists( system, workspace, lists, data->step, system->n, system->N, system->numH, comm ); }
void Bonds( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control ) { int i, j, pj, natoms; int start_i, end_i; int type_i, type_j; double ebond, pow_BOs_be2, exp_be12, CEbo; double gp3, gp4, gp7, gp10, gp37; double exphu, exphua1, exphub1, exphuov, hulpov, estriph; double decobdbo, decobdboua, decobdboub; single_body_parameters *sbp_i, *sbp_j; two_body_parameters *twbp; bond_order_data *bo_ij; reax_list *bonds; bonds = (*lists) + BONDS; gp3 = system->reax_param.gp.l[3]; gp4 = system->reax_param.gp.l[4]; gp7 = system->reax_param.gp.l[7]; gp10 = system->reax_param.gp.l[10]; gp37 = (int) system->reax_param.gp.l[37]; natoms = system->n; for( i = 0; i < natoms; ++i ) { start_i = Start_Index(i, bonds); end_i = End_Index(i, bonds); for( pj = start_i; pj < end_i; ++pj ) { j = bonds->select.bond_list[pj].nbr; if( system->my_atoms[i].orig_id > system->my_atoms[j].orig_id ) continue; if( system->my_atoms[i].orig_id == system->my_atoms[j].orig_id ) { if (system->my_atoms[j].x[2] < system->my_atoms[i].x[2]) continue; if (system->my_atoms[j].x[2] == system->my_atoms[i].x[2] && system->my_atoms[j].x[1] < system->my_atoms[i].x[1]) continue; if (system->my_atoms[j].x[2] == system->my_atoms[i].x[2] && system->my_atoms[j].x[1] == system->my_atoms[i].x[1] && system->my_atoms[j].x[0] < system->my_atoms[i].x[0]) continue; } /* set the pointers */ type_i = system->my_atoms[i].type; type_j = system->my_atoms[j].type; sbp_i = &( system->reax_param.sbp[type_i] ); sbp_j = &( system->reax_param.sbp[type_j] ); twbp = &( system->reax_param.tbp[type_i][type_j] ); bo_ij = &( bonds->select.bond_list[pj].bo_data ); /* calculate the constants */ pow_BOs_be2 = pow( bo_ij->BO_s, twbp->p_be2 ); exp_be12 = exp( twbp->p_be1 * ( 1.0 - pow_BOs_be2 ) ); CEbo = -twbp->De_s * exp_be12 * ( 1.0 - twbp->p_be1 * twbp->p_be2 * pow_BOs_be2 ); /* calculate the Bond Energy */ data->my_en.e_bond += ebond = -twbp->De_s * bo_ij->BO_s * exp_be12 -twbp->De_p * bo_ij->BO_pi -twbp->De_pp * bo_ij->BO_pi2; /* tally into per-atom energy */ if( system->pair_ptr->evflag) system->pair_ptr->ev_tally(i,j,natoms,1,ebond,0.0,0.0,0.0,0.0,0.0); /* calculate derivatives of Bond Orders */ bo_ij->Cdbo += CEbo; bo_ij->Cdbopi -= (CEbo + twbp->De_p); bo_ij->Cdbopi2 -= (CEbo + twbp->De_pp); /* Stabilisation terminal triple bond */ if( bo_ij->BO >= 1.00 ) { if( gp37 == 2 || (sbp_i->mass == 12.0000 && sbp_j->mass == 15.9990) || (sbp_j->mass == 12.0000 && sbp_i->mass == 15.9990) ) { exphu = exp( -gp7 * SQR(bo_ij->BO - 2.50) ); exphua1 = exp(-gp3 * (workspace->total_bond_order[i]-bo_ij->BO)); exphub1 = exp(-gp3 * (workspace->total_bond_order[j]-bo_ij->BO)); exphuov = exp(gp4 * (workspace->Delta[i] + workspace->Delta[j])); hulpov = 1.0 / (1.0 + 25.0 * exphuov); estriph = gp10 * exphu * hulpov * (exphua1 + exphub1); data->my_en.e_bond += estriph; decobdbo = gp10 * exphu * hulpov * (exphua1 + exphub1) * ( gp3 - 2.0 * gp7 * (bo_ij->BO-2.50) ); decobdboua = -gp10 * exphu * hulpov * (gp3*exphua1 + 25.0*gp4*exphuov*hulpov*(exphua1+exphub1)); decobdboub = -gp10 * exphu * hulpov * (gp3*exphub1 + 25.0*gp4*exphuov*hulpov*(exphua1+exphub1)); /* tally into per-atom energy */ if( system->pair_ptr->evflag) system->pair_ptr->ev_tally(i,j,natoms,1,estriph,0.0,0.0,0.0,0.0,0.0); bo_ij->Cdbo += decobdbo; workspace->CdDelta[i] += decobdboua; workspace->CdDelta[j] += decobdboub; } } } } }
void Estimate_Storages( reax_system *system, control_params *control, reax_list **lists, int *Htop, int *hb_top, int *bond_top, int *num_3body, MPI_Comm comm ) { int i, j, pj; int start_i, end_i; int type_i, type_j; int ihb, jhb; int local; double cutoff; double r_ij; double C12, C34, C56; double BO, BO_s, BO_pi, BO_pi2; reax_list *far_nbrs; single_body_parameters *sbp_i, *sbp_j; two_body_parameters *twbp; far_neighbor_data *nbr_pj; reax_atom *atom_i, *atom_j; int mincap = system->mincap; double safezone = system->safezone; double saferzone = system->saferzone; far_nbrs = *lists + FAR_NBRS; *Htop = 0; memset( hb_top, 0, sizeof(int) * system->local_cap ); memset( bond_top, 0, sizeof(int) * system->total_cap ); *num_3body = 0; for( i = 0; i < system->N; ++i ) { atom_i = &(system->my_atoms[i]); type_i = atom_i->type; if (type_i < 0) continue; start_i = Start_Index(i, far_nbrs); end_i = End_Index(i, far_nbrs); sbp_i = &(system->reax_param.sbp[type_i]); if( i < system->n ) { local = 1; cutoff = control->nonb_cut; ++(*Htop); ihb = sbp_i->p_hbond; } else { local = 0; cutoff = control->bond_cut; ihb = -1; } for( pj = start_i; pj < end_i; ++pj ) { nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); j = nbr_pj->nbr; atom_j = &(system->my_atoms[j]); if(nbr_pj->d <= cutoff) { type_j = system->my_atoms[j].type; if (type_j < 0) continue; r_ij = nbr_pj->d; sbp_j = &(system->reax_param.sbp[type_j]); twbp = &(system->reax_param.tbp[type_i][type_j]); if( local ) { if( j < system->n || atom_i->orig_id < atom_j->orig_id ) //tryQEq ||1 ++(*Htop); /* hydrogen bond lists */ if( control->hbond_cut > 0.1 && (ihb==1 || ihb==2) && nbr_pj->d <= control->hbond_cut ) { jhb = sbp_j->p_hbond; if( ihb == 1 && jhb == 2 ) ++hb_top[i]; else if( j < system->n && ihb == 2 && jhb == 1 ) ++hb_top[j]; } } /* uncorrected bond orders */ if( nbr_pj->d <= control->bond_cut ) { if( sbp_i->r_s > 0.0 && sbp_j->r_s > 0.0) { C12 = twbp->p_bo1 * pow( r_ij / twbp->r_s, twbp->p_bo2 ); BO_s = (1.0 + control->bo_cut) * exp( C12 ); } else BO_s = C12 = 0.0; if( sbp_i->r_pi > 0.0 && sbp_j->r_pi > 0.0) { C34 = twbp->p_bo3 * pow( r_ij / twbp->r_p, twbp->p_bo4 ); BO_pi = exp( C34 ); } else BO_pi = C34 = 0.0; if( sbp_i->r_pi_pi > 0.0 && sbp_j->r_pi_pi > 0.0) { C56 = twbp->p_bo5 * pow( r_ij / twbp->r_pp, twbp->p_bo6 ); BO_pi2= exp( C56 ); } else BO_pi2 = C56 = 0.0; /* Initially BO values are the uncorrected ones, page 1 */ BO = BO_s + BO_pi + BO_pi2; if( BO >= control->bo_cut ) { ++bond_top[i]; ++bond_top[j]; } } } } } *Htop = (int)(MAX( *Htop * safezone, mincap * MIN_HENTRIES )); for( i = 0; i < system->n; ++i ) hb_top[i] = (int)(MAX( hb_top[i] * saferzone, MIN_HBONDS )); for( i = 0; i < system->N; ++i ) { *num_3body += SQR(bond_top[i]); bond_top[i] = MAX( bond_top[i] * 2, MIN_BONDS ); } }
void vdW_Coulomb_Energy( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control ) { int i, j, pj, natoms; int start_i, end_i, orig_i, orig_j; real p_vdW1, p_vdW1i; real powr_vdW1, powgi_vdW1; real tmp, r_ij, fn13, exp1, exp2; real Tap, dTap, dfn13, CEvd, CEclmb, de_core; real dr3gamij_1, dr3gamij_3; real e_ele, e_vdW, e_core; rvec temp, ext_press; two_body_parameters *twbp; far_neighbor_data *nbr_pj; reax_list *far_nbrs; // rtensor temp_rtensor, total_rtensor; natoms = system->n; far_nbrs = (*lists) + FAR_NBRS; p_vdW1 = system->reax_param.gp.l[28]; p_vdW1i = 1.0 / p_vdW1; e_core = 0; e_vdW = 0; for( i = 0; i < natoms; ++i ) { start_i = Start_Index(i, far_nbrs); end_i = End_Index(i, far_nbrs); orig_i = system->my_atoms[i].orig_id; //fprintf( stderr, "i:%d, start_i: %d, end_i: %d\n", i, start_i, end_i ); for( pj = start_i; pj < end_i; ++pj ) { nbr_pj = &(far_nbrs->select.far_nbr_list[pj]); j = nbr_pj->nbr; orig_j = system->my_atoms[j].orig_id; if( nbr_pj->d <= control->nonb_cut && (j < natoms || orig_i < orig_j) ) { r_ij = nbr_pj->d; twbp = &(system->reax_param.tbp[ system->my_atoms[i].type ] [ system->my_atoms[j].type ]); /* Calculate Taper and its derivative */ // Tap = nbr_pj->Tap; -- precomputed during compte_H Tap = workspace->Tap[7] * r_ij + workspace->Tap[6]; Tap = Tap * r_ij + workspace->Tap[5]; Tap = Tap * r_ij + workspace->Tap[4]; Tap = Tap * r_ij + workspace->Tap[3]; Tap = Tap * r_ij + workspace->Tap[2]; Tap = Tap * r_ij + workspace->Tap[1]; Tap = Tap * r_ij + workspace->Tap[0]; dTap = 7*workspace->Tap[7] * r_ij + 6*workspace->Tap[6]; dTap = dTap * r_ij + 5*workspace->Tap[5]; dTap = dTap * r_ij + 4*workspace->Tap[4]; dTap = dTap * r_ij + 3*workspace->Tap[3]; dTap = dTap * r_ij + 2*workspace->Tap[2]; dTap += workspace->Tap[1]/r_ij; /*vdWaals Calculations*/ if(system->reax_param.gp.vdw_type==1 || system->reax_param.gp.vdw_type==3) { // shielding powr_vdW1 = pow(r_ij, p_vdW1); powgi_vdW1 = pow( 1.0 / twbp->gamma_w, p_vdW1); fn13 = pow( powr_vdW1 + powgi_vdW1, p_vdW1i ); exp1 = exp( twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); exp2 = exp( 0.5 * twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); e_vdW = twbp->D * (exp1 - 2.0 * exp2); data->my_en.e_vdW += Tap * e_vdW; dfn13 = pow( powr_vdW1 + powgi_vdW1, p_vdW1i - 1.0) * pow(r_ij, p_vdW1 - 2.0); CEvd = dTap * e_vdW - Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * (exp1 - exp2) * dfn13; } else{ // no shielding exp1 = exp( twbp->alpha * (1.0 - r_ij / twbp->r_vdW) ); exp2 = exp( 0.5 * twbp->alpha * (1.0 - r_ij / twbp->r_vdW) ); e_vdW = twbp->D * (exp1 - 2.0 * exp2); data->my_en.e_vdW += Tap * e_vdW; CEvd = dTap * e_vdW - Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * (exp1 - exp2) / r_ij; } if(system->reax_param.gp.vdw_type==2 || system->reax_param.gp.vdw_type==3) { // innner wall e_core = twbp->ecore * exp(twbp->acore * (1.0-(r_ij/twbp->rcore))); data->my_en.e_vdW += Tap * e_core; de_core = -(twbp->acore/twbp->rcore) * e_core; CEvd += dTap * e_core + Tap * de_core / r_ij; } /*Coulomb Calculations*/ dr3gamij_1 = ( r_ij * r_ij * r_ij + twbp->gamma ); dr3gamij_3 = pow( dr3gamij_1 , 0.33333333333333 ); tmp = Tap / dr3gamij_3; data->my_en.e_ele += e_ele = C_ele * system->my_atoms[i].q * system->my_atoms[j].q * tmp; CEclmb = C_ele * system->my_atoms[i].q * system->my_atoms[j].q * ( dTap - Tap * r_ij / dr3gamij_1 ) / dr3gamij_3; // fprintf( fout, "%5d %5d %10.6f %10.6f\n", // MIN( system->my_atoms[i].orig_id, system->my_atoms[j].orig_id ), // MAX( system->my_atoms[i].orig_id, system->my_atoms[j].orig_id ), // CEvd, CEclmb ); if( control->virial == 0 ) { rvec_ScaledAdd( workspace->f[i], -(CEvd + CEclmb), nbr_pj->dvec ); rvec_ScaledAdd( workspace->f[j], +(CEvd + CEclmb), nbr_pj->dvec ); } else { /* NPT, iNPT or sNPT */ /* for pressure coupling, terms not related to bond order derivatives are added directly into pressure vector/tensor */ rvec_Scale( temp, CEvd + CEclmb, nbr_pj->dvec ); rvec_ScaledAdd( workspace->f[i], -1., temp ); rvec_Add( workspace->f[j], temp ); rvec_iMultiply( ext_press, nbr_pj->rel_box, temp ); rvec_Add( data->my_ext_press, ext_press ); // fprintf( stderr, "nonbonded(%d,%d): rel_box (%f %f %f) // force(%f %f %f) ext_press (%12.6f %12.6f %12.6f)\n", // i, j, nbr_pj->rel_box[0], nbr_pj->rel_box[1], nbr_pj->rel_box[2], // temp[0], temp[1], temp[2], // data->ext_press[0], data->ext_press[1], data->ext_press[2] ); } #ifdef TEST_ENERGY // fprintf( out_control->evdw, // "%12.9f%12.9f%12.9f%12.9f%12.9f%12.9f%12.9f%12.9f\n", // workspace->Tap[7],workspace->Tap[6],workspace->Tap[5], // workspace->Tap[4],workspace->Tap[3],workspace->Tap[2], // workspace->Tap[1], Tap ); //fprintf( out_control->evdw, "%6d%6d%24.15e%24.15e%24.15e\n", fprintf( out_control->evdw, "%6d%6d%12.4f%12.4f%12.4f\n", system->my_atoms[i].orig_id, system->my_atoms[j].orig_id, r_ij, e_vdW, data->my_en.e_vdW ); //fprintf(out_control->ecou,"%6d%6d%24.15e%24.15e%24.15e%24.15e%24.15e\n", fprintf( out_control->ecou, "%6d%6d%12.4f%12.4f%12.4f%12.4f%12.4f\n", system->my_atoms[i].orig_id, system->my_atoms[j].orig_id, r_ij, system->my_atoms[i].q, system->my_atoms[j].q, e_ele, data->my_en.e_ele ); #endif #ifdef TEST_FORCES rvec_ScaledAdd( workspace->f_vdw[i], -CEvd, nbr_pj->dvec ); rvec_ScaledAdd( workspace->f_vdw[j], +CEvd, nbr_pj->dvec ); rvec_ScaledAdd( workspace->f_ele[i], -CEclmb, nbr_pj->dvec ); rvec_ScaledAdd( workspace->f_ele[j], +CEclmb, nbr_pj->dvec ); #endif } } } #if defined(DEBUG) fprintf( stderr, "nonbonded: ext_press (%12.6f %12.6f %12.6f)\n", data->ext_press[0], data->ext_press[1], data->ext_press[2] ); MPI_Barrier( MPI_COMM_WORLD ); #endif Compute_Polarization_Energy( system, data ); }
void Add_dBond_to_Forces_NPT( int i, int pj, simulation_data *data, storage *workspace, reax_list **lists ) { reax_list *bonds = (*lists) + BONDS; bond_data *nbr_j, *nbr_k; bond_order_data *bo_ij, *bo_ji; dbond_coefficients coef; rvec temp, ext_press; ivec rel_box; int pk, k, j; /* Initializations */ nbr_j = &(bonds->select.bond_list[pj]); j = nbr_j->nbr; bo_ij = &(nbr_j->bo_data); bo_ji = &(bonds->select.bond_list[ nbr_j->sym_index ].bo_data); coef.C1dbo = bo_ij->C1dbo * (bo_ij->Cdbo + bo_ji->Cdbo); coef.C2dbo = bo_ij->C2dbo * (bo_ij->Cdbo + bo_ji->Cdbo); coef.C3dbo = bo_ij->C3dbo * (bo_ij->Cdbo + bo_ji->Cdbo); coef.C1dbopi = bo_ij->C1dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); coef.C2dbopi = bo_ij->C2dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); coef.C3dbopi = bo_ij->C3dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); coef.C4dbopi = bo_ij->C4dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); coef.C1dbopi2 = bo_ij->C1dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); coef.C2dbopi2 = bo_ij->C2dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); coef.C3dbopi2 = bo_ij->C3dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); coef.C4dbopi2 = bo_ij->C4dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); coef.C1dDelta = bo_ij->C1dbo * (workspace->CdDelta[i]+workspace->CdDelta[j]); coef.C2dDelta = bo_ij->C2dbo * (workspace->CdDelta[i]+workspace->CdDelta[j]); coef.C3dDelta = bo_ij->C3dbo * (workspace->CdDelta[i]+workspace->CdDelta[j]); for( pk = Start_Index(i, bonds); pk < End_Index(i, bonds); ++pk ) { nbr_k = &(bonds->select.bond_list[pk]); k = nbr_k->nbr; rvec_Scale(temp, -coef.C2dbo, nbr_k->bo_data.dBOp); /*2nd, dBO*/ rvec_ScaledAdd(temp, -coef.C2dDelta, nbr_k->bo_data.dBOp);/*dDelta*/ rvec_ScaledAdd(temp, -coef.C3dbopi, nbr_k->bo_data.dBOp); /*3rd, dBOpi*/ rvec_ScaledAdd(temp, -coef.C3dbopi2, nbr_k->bo_data.dBOp);/*3rd, dBOpi2*/ /* force */ rvec_Add( workspace->f[k], temp ); /* pressure */ rvec_iMultiply( ext_press, nbr_k->rel_box, temp ); rvec_Add( data->my_ext_press, ext_press ); } /* then atom i itself */ rvec_Scale( temp, coef.C1dbo, bo_ij->dBOp ); /*1st,dBO*/ rvec_ScaledAdd( temp, coef.C2dbo, workspace->dDeltap_self[i] ); /*2nd,dBO*/ rvec_ScaledAdd( temp, coef.C1dDelta, bo_ij->dBOp ); /*1st,dBO*/ rvec_ScaledAdd( temp, coef.C2dDelta, workspace->dDeltap_self[i] );/*2nd,dBO*/ rvec_ScaledAdd( temp, coef.C1dbopi, bo_ij->dln_BOp_pi ); /*1st,dBOpi*/ rvec_ScaledAdd( temp, coef.C2dbopi, bo_ij->dBOp ); /*2nd,dBOpi*/ rvec_ScaledAdd( temp, coef.C3dbopi, workspace->dDeltap_self[i]);/*3rd,dBOpi*/ rvec_ScaledAdd( temp, coef.C1dbopi2, bo_ij->dln_BOp_pi2 ); /*1st,dBO_pi2*/ rvec_ScaledAdd( temp, coef.C2dbopi2, bo_ij->dBOp ); /*2nd,dBO_pi2*/ rvec_ScaledAdd( temp, coef.C3dbopi2, workspace->dDeltap_self[i] );/*3rd*/ /* force */ rvec_Add( workspace->f[i], temp ); for( pk = Start_Index(j, bonds); pk < End_Index(j, bonds); ++pk ) { nbr_k = &(bonds->select.bond_list[pk]); k = nbr_k->nbr; rvec_Scale( temp, -coef.C3dbo, nbr_k->bo_data.dBOp ); /*3rd,dBO*/ rvec_ScaledAdd( temp, -coef.C3dDelta, nbr_k->bo_data.dBOp);/*dDelta*/ rvec_ScaledAdd( temp, -coef.C4dbopi, nbr_k->bo_data.dBOp); /*4th,dBOpi*/ rvec_ScaledAdd( temp, -coef.C4dbopi2, nbr_k->bo_data.dBOp);/*4th,dBOpi2*/ /* force */ rvec_Add( workspace->f[k], temp ); /* pressure */ if( k != i ) { ivec_Sum( rel_box, nbr_k->rel_box, nbr_j->rel_box ); //rel_box(k, i) rvec_iMultiply( ext_press, rel_box, temp ); rvec_Add( data->my_ext_press, ext_press ); } } /* then atom j itself */ rvec_Scale( temp, -coef.C1dbo, bo_ij->dBOp ); /*1st, dBO*/ rvec_ScaledAdd( temp, coef.C3dbo, workspace->dDeltap_self[j] ); /*2nd, dBO*/ rvec_ScaledAdd( temp, -coef.C1dDelta, bo_ij->dBOp ); /*1st, dBO*/ rvec_ScaledAdd( temp, coef.C3dDelta, workspace->dDeltap_self[j]);/*2nd, dBO*/ rvec_ScaledAdd( temp, -coef.C1dbopi, bo_ij->dln_BOp_pi ); /*1st,dBOpi*/ rvec_ScaledAdd( temp, -coef.C2dbopi, bo_ij->dBOp ); /*2nd,dBOpi*/ rvec_ScaledAdd( temp, coef.C4dbopi, workspace->dDeltap_self[j]);/*3rd,dBOpi*/ rvec_ScaledAdd( temp, -coef.C1dbopi2, bo_ij->dln_BOp_pi2 ); /*1st,dBOpi2*/ rvec_ScaledAdd( temp, -coef.C2dbopi2, bo_ij->dBOp ); /*2nd,dBOpi2*/ rvec_ScaledAdd( temp,coef.C4dbopi2,workspace->dDeltap_self[j]);/*3rd,dBOpi2*/ /* force */ rvec_Add( workspace->f[j], temp ); /* pressure */ rvec_iMultiply( ext_press, nbr_j->rel_box, temp ); rvec_Add( data->my_ext_press, ext_press ); }