void Generate_Initial_Velocities( reax_system *system, real T ) { int i; real m, scale, norm; if( T <= 0.1 ) { for( i = 0; i < system->n; i++ ) rvec_MakeZero( system->my_atoms[i].v ); } else { Randomize(); for( i = 0; i < system->n; i++ ) { rvec_Random( system->my_atoms[i].v ); norm = rvec_Norm_Sqr( system->my_atoms[i].v ); m = system->reax_param.sbp[ system->my_atoms[i].type ].mass; scale = sqrt( m * norm / (3.0 * K_B * T) ); rvec_Scale( system->my_atoms[i].v, 1./scale, system->my_atoms[i].v ); // fprintf( stderr, "v = %f %f %f\n", // system->my_atoms[i].v[0], // system->my_atoms[i].v[1], // system->my_atoms[i].v[2] ); // fprintf( stderr, "scale = %f\n", scale ); // fprintf( stderr, "v = %f %f %f\n", // system->my_atoms[i].v[0], // system->my_atoms[i].v[1], // system->my_atoms[i].v[2] ); } } }
void Calculate_Drift( reax_system *system, control_params *control, simulation_data *data, static_storage *workspace, FILE *fout ) { int i, type; int count[MAX_ATOM_TYPES]; real drift; rvec driftvec; real sum_sqr_drift[MAX_ATOM_TYPES], sum_drift[MAX_ATOM_TYPES]; for( i = 0; i < MAX_ATOM_TYPES; ++i ) { count[i] = 0; sum_sqr_drift[i] = sum_drift[i] = 0.0; } for( i = 0; i < system->N; ++i ) //if( control->restrict_type == -1 || // system->atoms[i].type == control->restrict_type ) if( workspace->x_old[i][0] > -system->box.box_norms[0] && workspace->x_old[i][1] > -system->box.box_norms[1] && workspace->x_old[i][2] > -system->box.box_norms[2] ) { type = system->atoms[i].type; ++count[type]; Distance_on_T3_Gen( workspace->x_old[i], system->atoms[i].x, &(system->box), driftvec ); if( fabs( driftvec[0] ) >= system->box.box_norms[0] / 2.0 - 2.0 || fabs( driftvec[0] ) >= system->box.box_norms[0] / 2.0 - 2.0 || fabs( driftvec[0] ) >= system->box.box_norms[0] / 2.0 - 2.0 ) { /* the atom has moved almost half the box size. exclude it from further drift computations as it might have an improper contribution due to periodic boudnaries. */ workspace->x_old[i][0] = workspace->x_old[i][2] = workspace->x_old[i][2] = -999999999999.0; continue; } drift = rvec_Norm_Sqr( driftvec ); sum_sqr_drift[type] += drift; sum_drift[type] += SQRT( drift ); } fprintf( fout, "%7d oxy %6d %10.6f\n", data->step, count[2], sum_sqr_drift[2] / count[2] ); fprintf( fout, "%7d hyd %6d %10.6f\n", data->step, count[1], sum_sqr_drift[1] / count[1] ); fflush( fout ); }
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 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 Compute_Center_of_Mass( reax_system *system, simulation_data *data, mpi_datatypes *mpi_data, MPI_Comm comm ) { int i; double m, det; //xx, xy, xz, yy, yz, zz; double tmp_mat[6], tot_mat[6]; rvec my_xcm, my_vcm, my_amcm, my_avcm; rvec tvec, diff; rtensor mat, inv; rvec_MakeZero( my_xcm ); // position of CoM rvec_MakeZero( my_vcm ); // velocity of CoM rvec_MakeZero( my_amcm ); // angular momentum of CoM rvec_MakeZero( my_avcm ); // angular velocity of CoM /* Compute the position, vel. and ang. momentum about the centre of mass */ for( i = 0; i < system->n; ++i ) { m = system->reax_param.sbp[ system->my_atoms[i].type ].mass; rvec_ScaledAdd( my_xcm, m, system->my_atoms[i].x ); rvec_ScaledAdd( my_vcm, m, system->my_atoms[i].v ); rvec_Cross( tvec, system->my_atoms[i].x, system->my_atoms[i].v ); rvec_ScaledAdd( my_amcm, m, tvec ); } MPI_Allreduce( my_xcm, data->xcm, 3, MPI_DOUBLE, MPI_SUM, comm ); MPI_Allreduce( my_vcm, data->vcm, 3, MPI_DOUBLE, MPI_SUM, comm ); MPI_Allreduce( my_amcm, data->amcm, 3, MPI_DOUBLE, MPI_SUM, comm ); rvec_Scale( data->xcm, data->inv_M, data->xcm ); rvec_Scale( data->vcm, data->inv_M, data->vcm ); rvec_Cross( tvec, data->xcm, data->vcm ); rvec_ScaledAdd( data->amcm, -data->M, tvec ); data->etran_cm = 0.5 * data->M * rvec_Norm_Sqr( data->vcm ); /* Calculate and then invert the inertial tensor */ for( i = 0; i < 6; ++i ) tmp_mat[i] = 0; //my_xx = my_xy = my_xz = my_yy = my_yz = my_zz = 0; for( i = 0; i < system->n; ++i ){ m = system->reax_param.sbp[ system->my_atoms[i].type ].mass; rvec_ScaledSum( diff, 1., system->my_atoms[i].x, -1., data->xcm ); tmp_mat[0]/*my_xx*/ += diff[0] * diff[0] * m; tmp_mat[1]/*my_xy*/ += diff[0] * diff[1] * m; tmp_mat[2]/*my_xz*/ += diff[0] * diff[2] * m; tmp_mat[3]/*my_yy*/ += diff[1] * diff[1] * m; tmp_mat[4]/*my_yz*/ += diff[1] * diff[2] * m; tmp_mat[5]/*my_zz*/ += diff[2] * diff[2] * m; } MPI_Reduce( tmp_mat, tot_mat, 6, MPI_DOUBLE, MPI_SUM, MASTER_NODE, comm ); if( system->my_rank == MASTER_NODE ) { mat[0][0] = tot_mat[3] + tot_mat[5]; // yy + zz; mat[0][1] = mat[1][0] = -tot_mat[1]; // -xy; mat[0][2] = mat[2][0] = -tot_mat[2]; // -xz; mat[1][1] = tot_mat[0] + tot_mat[5]; // xx + zz; mat[2][1] = mat[1][2] = -tot_mat[4]; // -yz; mat[2][2] = tot_mat[0] + tot_mat[3]; // xx + yy; /* invert the inertial tensor */ det = ( mat[0][0] * mat[1][1] * mat[2][2] + mat[0][1] * mat[1][2] * mat[2][0] + mat[0][2] * mat[1][0] * mat[2][1] ) - ( mat[0][0] * mat[1][2] * mat[2][1] + mat[0][1] * mat[1][0] * mat[2][2] + mat[0][2] * mat[1][1] * mat[2][0] ); inv[0][0] = mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]; inv[0][1] = mat[0][2] * mat[2][1] - mat[0][1] * mat[2][2]; inv[0][2] = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1]; inv[1][0] = mat[1][2] * mat[2][0] - mat[1][0] * mat[2][2]; inv[1][1] = mat[0][0] * mat[2][2] - mat[0][2] * mat[2][0]; inv[1][2] = mat[0][2] * mat[1][0] - mat[0][0] * mat[1][2]; inv[2][0] = mat[1][0] * mat[2][1] - mat[2][0] * mat[1][1]; inv[2][1] = mat[2][0] * mat[0][1] - mat[0][0] * mat[2][1]; inv[2][2] = mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1]; if( det > ALMOST_ZERO ) rtensor_Scale( inv, 1./det, inv ); else rtensor_MakeZero( inv ); /* Compute the angular velocity about the centre of mass */ rtensor_MatVec( data->avcm, inv, data->amcm ); } MPI_Bcast( data->avcm, 3, MPI_DOUBLE, MASTER_NODE, comm ); /* Compute the rotational energy */ data->erot_cm = 0.5 * E_CONV * rvec_Dot( data->avcm, data->amcm ); }