diff --git a/sPuReMD/src/analyze.c b/sPuReMD/src/analyze.c index fa83135365692fc8be8e90c8a86ca0b69ca4276b..33e5e1cdf0644add0906051fd8de36fa5002b7bd 100644 --- a/sPuReMD/src/analyze.c +++ b/sPuReMD/src/analyze.c @@ -337,6 +337,7 @@ static void Analyze_Molecules( reax_system *system, control_params *control, } +#if defined(DEBUG_FOCUS) static void Report_Bond_Change( reax_system *system, control_params *control, static_storage *workspace, reax_list *old_bonds, reax_list *new_bonds, int a1, int a2, int flag, FILE *fout ) @@ -436,9 +437,11 @@ static void Report_Bond_Change( reax_system *system, control_params *control, fprintf( fout, "\n" ); } } +#endif /* ASSUMPTION: Bond lists are sorted */ +#if defined(DEBUG_FOCUS) static void Compare_Bonding( int atom, reax_system *system, control_params *control, static_storage *workspace, reax_list *old_bonds, reax_list *new_bonds, FILE *fout ) @@ -563,6 +566,7 @@ static void Compare_Bonding( int atom, reax_system *system, control_params *cont } } } +#endif static void Visit_Bonds( int atom, int *mark, int *type, reax_system *system, @@ -642,7 +646,7 @@ static void Analyze_Fragments( reax_system *system, control_params *control, { /* it is a new one, add to the fragments list */ strncpy( fragments[num_fragment_types], fragment_out, - sizeof(fragments[num_fragment_types]) - 1 ); + sizeof(fragments[num_fragment_types]) ); fragments[num_fragment_types][sizeof(fragments[num_fragment_types]) - 1] = '\0'; fragment_count[num_fragment_types] = 1; ++num_fragment_types; @@ -671,6 +675,7 @@ static void Analyze_Fragments( reax_system *system, control_params *control, } +#if defined(DEBUG_FOCUS) static void Analyze_Silica( reax_system *system, control_params *control, simulation_data *data, static_storage *workspace, reax_list **lists, FILE *fout ) @@ -798,6 +803,7 @@ static void Analyze_Silica( reax_system *system, control_params *control, fflush( fout ); } +#endif static int Get_Type_of_Molecule( molecule *m ) @@ -932,6 +938,7 @@ static void Calculate_Drift( reax_system *system, control_params *control, } +#if defined(DEBUG_FOCUS) static void Calculate_Density_3DMesh( reax_system *system, simulation_data *data, FILE *fout ) { @@ -1009,8 +1016,10 @@ static void Calculate_Density_3DMesh( reax_system *system, simulation_data *data fprintf( stderr, "AMU_to_GRAM : %g\n", AMU_to_GRAM ); fprintf( stderr, "ANG_to_CM : %g\n", ANG_to_CM ); } +#endif +#if defined(DEBUG_FOCUS) static void Calculate_Density_Slice( reax_system *system, simulation_data *data, FILE *fout ) { real slice_thickness = 0.5; @@ -1049,11 +1058,12 @@ static void Calculate_Density_Slice( reax_system *system, simulation_data *data, } } } +#endif void Analysis( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - reax_list **lists, output_controls *out_control ) + simulation_data *data, static_storage *workspace, + reax_list **lists, output_controls *out_control ) { int steps; @@ -1061,6 +1071,12 @@ void Analysis( reax_system *system, control_params *control, if ( steps == 1 ) { + if ( lists[OLD_BONDS]->allocated == FALSE ) + { + Make_List( lists[BONDS]->n, lists[BONDS]->n_max, lists[BONDS]->total_intrs, + TYP_BOND, lists[OLD_BONDS] ); + } + if ( control->molec_anal == REACTIONS ) { Copy_Bond_List( system, control, lists ); @@ -1072,25 +1088,26 @@ void Analysis( reax_system *system, control_params *control, } /****** Molecular Analysis ******/ - if ( control->molec_anal && steps % control->freq_molec_anal == 0 ) + if ( control->molec_anal + && steps % control->freq_molec_anal == 0 ) { if ( control->molec_anal == FRAGMENTS ) { /* discover molecules */ Analyze_Fragments( system, control, data, workspace, lists, - out_control->mol, 0 ); + out_control->mol, 0 ); /* discover fragments without the ignored atoms */ if ( control->num_ignored ) { Analyze_Fragments( system, control, data, workspace, lists, - out_control->ign, 1 ); + out_control->ign, 1 ); } } else if ( control->molec_anal == REACTIONS ) { /* discover molecular changes - reactions */ - Analyze_Molecules( system, control, data, workspace, - lists, out_control->mol ); + Analyze_Molecules( system, control, data, workspace, lists, + out_control->mol ); } } diff --git a/sPuReMD/src/bond_orders.c b/sPuReMD/src/bond_orders.c index 294dac11b06dc768464b7ccd09666000388dde7f..bc60d19321ad3f0715bfa5817756edfe615a9390 100644 --- a/sPuReMD/src/bond_orders.c +++ b/sPuReMD/src/bond_orders.c @@ -1072,10 +1072,10 @@ void BO( reax_system *system, control_params *control, 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])); + explp1 = EXP( -1.0 * 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->Clp[j] = 2.0 * p_lp1 * (2.0 + workspace->vlpex[j]) * explp1; /* Adri uses different dDelta_lp values than the ones in notes... */ workspace->dDelta_lp[j] = workspace->Clp[j]; // workspace->dDelta_lp[j] = workspace->Clp[j] + (0.5 - workspace->Clp[j]) diff --git a/sPuReMD/src/charges.c b/sPuReMD/src/charges.c index f3311c1a185370e9bc8d046d2d85a0043de50c42..998357a81743362acc038fceddef5dcfb7f33b11 100644 --- a/sPuReMD/src/charges.c +++ b/sPuReMD/src/charges.c @@ -1518,6 +1518,9 @@ static void EE( reax_system * const system, control_params * const control, workspace->mask_qmmm[i] = system->atoms[i].qmmm_mask; } workspace->mask_qmmm[system->N_cm - 1] = 1; + + /* Mask the b vector as well */ + Vector_Mask_qmmm( workspace->b_s, workspace->mask_qmmm, system->N_cm ); #endif switch ( control->cm_solver_type ) @@ -1646,8 +1649,11 @@ static void ACKS2( reax_system * const system, control_params * const control, { workspace->mask_qmmm[i] = system->atoms[i - system->N].qmmm_mask; } - workspace->mask_qmmm[2 * system->N_cm] = 1; - workspace->mask_qmmm[2 * system->N_cm + 1] = 1; + workspace->mask_qmmm[2 * system->N] = 1; + workspace->mask_qmmm[2 * system->N + 1] = 1; + + /* Mask the b vector as well */ + Vector_Mask_qmmm( workspace->b_s, workspace->mask_qmmm, system->N_cm ); #endif switch ( control->cm_solver_type ) diff --git a/sPuReMD/src/ffield.c b/sPuReMD/src/ffield.c index 569b6844168fa3ce2b2d4dd09ebea28018c65853..39d78b2026a56c217ca3ab32dc55e8bd93f09f89 100644 --- a/sPuReMD/src/ffield.c +++ b/sPuReMD/src/ffield.c @@ -257,7 +257,8 @@ void Read_Force_Field( const char * const ffield_file, fgets( s, MAX_LINE, fp ); Tokenize( s, &tmp, MAX_TOKEN_LEN ); - strncpy( reax->sbp[i].name, tmp[0], sizeof(reax->sbp[i].name) ); + strncpy( reax->sbp[i].name, tmp[0], sizeof(reax->sbp[i].name) - 1 ); + reax->sbp[i].name[sizeof(reax->sbp[i].name) - 1] = '\0'; for ( j = 0; j < strlen( reax->sbp[i].name ); ++j ) { reax->sbp[i].name[j] = toupper( reax->sbp[i].name[j] ); diff --git a/sPuReMD/src/forces.c b/sPuReMD/src/forces.c index 6e2fc638af30e704e420b227204fb5e6d123a471..4b42eaa0bf677acd230ee6e337445aee275ed382 100644 --- a/sPuReMD/src/forces.c +++ b/sPuReMD/src/forces.c @@ -493,49 +493,101 @@ static void Init_Charge_Matrix_Remaining_Entries( reax_system *system, break; case EE_CM: - H->start[system->N_cm - 1] = *Htop; - H_sp->start[system->N_cm - 1] = *H_sp_top; - - for ( i = 0; i < system->N_cm - 1; ++i ) + if ( system->num_molec_charge_constraints == 0 ) { -#if defined(QMMM) - // total charge constraint on QM atoms - if ( system->atoms[i].qmmm_mask == TRUE ) + H->start[system->N_cm - 1] = *Htop; + H_sp->start[system->N_cm - 1] = *H_sp_top; + + for ( i = 0; i < system->N_cm - 1; ++i ) { +#if defined(QMMM) + /* total charge constraint on QM atoms */ + if ( system->atoms[i].qmmm_mask == TRUE ) + { + H->j[*Htop] = i; + H->val[*Htop] = 1.0; + + H_sp->j[*H_sp_top] = i; + H_sp->val[*H_sp_top] = 1.0; + } + else + { + H->j[*Htop] = i; + H->val[*Htop] = 0.0; + + H_sp->j[*H_sp_top] = i; + H_sp->val[*H_sp_top] = 0.0; + } +#else H->j[*Htop] = i; H->val[*Htop] = 1.0; H_sp->j[*H_sp_top] = i; H_sp->val[*H_sp_top] = 1.0; - } - else - { - H->j[*Htop] = i; - H->val[*Htop] = 0.0; +#endif - H_sp->j[*H_sp_top] = i; - H_sp->val[*H_sp_top] = 0.0; + *Htop = *Htop + 1; + *H_sp_top = *H_sp_top + 1; } + + H->j[*Htop] = system->N_cm - 1; + H->val[*Htop] = 0.0; *Htop = *Htop + 1; + + H_sp->j[*H_sp_top] = system->N_cm - 1; + H_sp->val[*H_sp_top] = 0.0; *H_sp_top = *H_sp_top + 1; + } + else + { + for ( i = 0; i < system->num_molec_charge_constraints; ++i ) + { + H->start[system->N + i] = *Htop; + H_sp->start[system->N + i] = *H_sp_top; + + for ( j = system->molec_charge_constraint_ranges[2 * i]; + j <= system->molec_charge_constraint_ranges[2 * i + 1]; ++j ) + { +#if defined(QMMM) + /* molecule charge constraint on QM atoms */ + if ( system->atoms[i].qmmm_mask == TRUE ) + { + H->j[*Htop] = j - 1; + H->val[*Htop] = 1.0; + + H_sp->j[*H_sp_top] = j - 1; + H_sp->val[*H_sp_top] = 1.0; + } + else + { + H->j[*Htop] = j - 1; + H->val[*Htop] = 0.0; + + H_sp->j[*H_sp_top] = j - 1; + H_sp->val[*H_sp_top] = 0.0; + } #else - H->j[*Htop] = i; - H->val[*Htop] = 1.0; - *Htop = *Htop + 1; + H->j[*Htop] = j - 1; + H->val[*Htop] = 1.0; - H_sp->j[*H_sp_top] = i; - H_sp->val[*H_sp_top] = 1.0; - *H_sp_top = *H_sp_top + 1; + H_sp->j[*H_sp_top] = j - 1; + H_sp->val[*H_sp_top] = 1.0; #endif - } - H->j[*Htop] = system->N_cm - 1; - H->val[*Htop] = 0.0; - *Htop = *Htop + 1; + *Htop = *Htop + 1; + *H_sp_top = *H_sp_top + 1; + } - H_sp->j[*H_sp_top] = system->N_cm - 1; - H_sp->val[*H_sp_top] = 0.0; - *H_sp_top = *H_sp_top + 1; + /* explicit zeros on diagonals */ + H->j[*Htop] = system->N + i; + H->val[*Htop] = 0.0; + *Htop = *Htop + 1; + + H_sp->j[*H_sp_top] = system->N + i; + H_sp->val[*H_sp_top] = 0.0; + *H_sp_top = *H_sp_top + 1; + } + } break; case ACKS2_CM: @@ -793,6 +845,11 @@ static void Init_Forces( reax_system *system, control_params *control, flag = FALSE; flag_sp = FALSE; +#if defined(QMMM) + if ( system->atoms[i].qmmm_mask == TRUE + || system->atoms[j].qmmm_mask == TRUE ) + { +#endif /* check if reneighboring step -- * atomic distances just computed via * Verlet list, so use current distances */ @@ -1024,11 +1081,14 @@ static void Init_Forces( reax_system *system, control_params *control, Set_End_Index( j, btop_j + 1, bonds ); } +#if defined(QMMM) + } +#endif } - } #if defined(QMMM) } #endif + } } /* diagonal entry */ diff --git a/sPuReMD/src/geo_tools.c b/sPuReMD/src/geo_tools.c index 3b361e20f487a213891a2f1975c319421d617459..32e0fe573c97062b9b89904fd4b2f37f2ce6c132 100644 --- a/sPuReMD/src/geo_tools.c +++ b/sPuReMD/src/geo_tools.c @@ -359,7 +359,7 @@ void Read_PDB( const char * const pdb_file, reax_system* system, control_params char s_x[9], s_y[9], s_z[9]; char occupancy[7], temp_factor[7]; char seg_id[5], element[3], charge[3]; - char alt_loc, chain_id, icode; +// char alt_loc, chain_id, icode; rvec x; reax_atom *atom; @@ -409,13 +409,13 @@ void Read_PDB( const char * const pdb_file, reax_system* system, control_params serial[sizeof(serial) - 1] = '\0'; strncpy( atom_name, s1 + 12, sizeof(atom_name) - 1 ); atom_name[sizeof(atom_name) - 1] = '\0'; - alt_loc = s1[16]; +// alt_loc = s1[16]; strncpy( res_name, s1 + 17, sizeof(res_name) - 1 ); res_name[sizeof(res_name) - 1] = '\0'; - chain_id = s1[21]; +// chain_id = s1[21]; strncpy( res_seq, s1 + 22, sizeof(res_seq) - 1 ); res_seq[sizeof(res_seq) - 1] = '\0'; - icode = s1[26]; +// icode = s1[26]; strncpy( s_x, s1 + 30, sizeof(s_x) - 1 ); s_x[sizeof(s_x) - 1] = '\0'; strncpy( s_y, s1 + 38, sizeof(s_y) - 1 ); @@ -441,13 +441,13 @@ void Read_PDB( const char * const pdb_file, reax_system* system, control_params serial[sizeof(serial) - 1] = '\0'; strncpy( atom_name, s1 + 12, sizeof(atom_name) - 1 ); atom_name[sizeof(atom_name) - 1] = '\0'; - alt_loc = s1[16]; +// alt_loc = s1[16]; strncpy( res_name, s1 + 17, sizeof(res_name) - 1 ); res_name[sizeof(res_name) - 1] = '\0'; - chain_id = s1[21]; +// chain_id = s1[21]; strncpy( res_seq, s1 + 22, sizeof(res_seq) - 1 ); res_seq[sizeof(res_seq) - 1] = '\0'; - icode = s1[26]; +// icode = s1[26]; strncpy( s_x, s1 + 30, sizeof(s_x) - 1 ); s_x[sizeof(s_x) - 1] = '\0'; strncpy( s_y, s1 + 38, sizeof(s_y) - 1 ); @@ -589,7 +589,12 @@ void Write_PDB( reax_system* system, reax_list* bonds, simulation_data *data, / (system->box.box_norms[2] * system->box.box_norms[1]) ); /* write header */ - snprintf( fname, sizeof(fname), "%s-%d.pdb", control->sim_name, data->step ); + snprintf( fname, sizeof(fname) - 1, "%.*s-%.*d.pdb", + (int) MIN( strnlen(control->sim_name, + sizeof(fname) - snprintf(NULL, 0, "%d", data->step) - 6 ), + sizeof(control->sim_name) ), + control->sim_name, snprintf(NULL, 0, "%d", data->step), data->step ); + fname[sizeof(fname) - 1] = '\0'; pdb = sfopen( fname, "w" ); fprintf( pdb, PDB_CRYST1_FORMAT_O, "CRYST1", @@ -625,6 +630,13 @@ void Write_PDB( reax_system* system, reax_list* bonds, simulation_data *data, } +/* Parser for geometry files in BGF format + * + * system: struct containing atom-related information + * control: struct containing simulation parameters + * data: struct containing information on active simulations + * workspace: struct containing intermediate structures used for calculations + * */ void Read_BGF( const char * const bgf_file, reax_system* system, control_params *control, simulation_data *data, static_storage *workspace ) { @@ -636,9 +648,9 @@ void Read_BGF( const char * const bgf_file, reax_system* system, control_params char s_x[11], s_y[11], s_z[11]; char occupancy[4], temp_factor[3]; char element[6], charge[9]; - char chain_id; +// char chain_id; char s_a[12], s_b[12], s_c[12], s_alpha[12], s_beta[12], s_gamma[12]; - int i, n, atom_cnt, token_cnt, bgf_serial, ratom, crystx_found; + int i, n, num_mcc, atom_cnt, token_cnt, bgf_serial, ratom, crystx_found; rvec x; ratom = 0; @@ -651,6 +663,7 @@ void Read_BGF( const char * const bgf_file, reax_system* system, control_params /* count number of atoms in the BGF file */ n = 0; + num_mcc = 0; line[0] = 0; while ( fgets( line, MAX_LINE, bgf ) ) @@ -663,6 +676,10 @@ void Read_BGF( const char * const bgf_file, reax_system* system, control_params { ++n; } + else if ( strncmp( tokens[0], "MOLCHARGE", 9 ) == 0 ) + { + ++num_mcc; + } line[0] = 0; } @@ -672,20 +689,50 @@ void Read_BGF( const char * const bgf_file, reax_system* system, control_params exit( INVALID_INPUT ); } - sfclose( bgf, "Read_BGF::bgf" ); - if ( system->prealloc_allocated == FALSE || n > system->N_max ) { PreAllocate_Space( system, control, workspace, (int) CEIL( SAFE_ZONE * n ) ); + + if ( system->prealloc_allocated == FALSE && num_mcc > 0 ) + { + system->molec_charge_constraints = smalloc( + sizeof(real) * num_mcc, "Read_BGF::molec_charge_constraints" ); + system->molec_charge_constraint_ranges = smalloc( + sizeof(int) * 2 * num_mcc, "Read_BGF::molec_charge_constraint_ranges" ); + + system->max_num_molec_charge_constraints = num_mcc; + } + else if ( num_mcc > system->max_num_molec_charge_constraints ) + { + if ( system->max_num_molec_charge_constraints > 0 ) + { + sfree( system->molec_charge_constraints, "Read_BGF::molec_charge_constraints" ); + sfree( system->molec_charge_constraint_ranges, "Read_BGF::molec_charge_constraint_ranges" ); + } + + system->molec_charge_constraints = smalloc( + sizeof(real) * num_mcc, "Read_BGF::molec_charge_constraints" ); + system->molec_charge_constraint_ranges = smalloc( + sizeof(int) * 2 * num_mcc, "Read_BGF::molec_charge_constraint_ranges" ); + + system->max_num_molec_charge_constraints = num_mcc; + } } system->N = n; + system->num_molec_charge_constraints = num_mcc; + num_mcc = 0; + +#if defined(DEBUG_FOCUS) + fprintf( stderr, "[INFO] num_atoms = %d, num_mcc = %d\n", system->N, + system->num_molec_charge_constraints ); +#endif for ( i = 0; i < MAX_ATOM_ID; ++i ) { workspace->map_serials[i] = -1; } - bgf = sfopen( bgf_file, "r" ); + fseek( bgf, 0, SEEK_SET ); atom_cnt = 0; token_cnt = 0; @@ -748,7 +795,7 @@ void Read_BGF( const char * const bgf_file, reax_system* system, control_params atom_name[sizeof(atom_name) - 1] = '\0'; strncpy( res_name, backup + 19, sizeof(res_name) - 1 ); res_name[sizeof(res_name) - 1] = '\0'; - chain_id = backup[23]; +// chain_id = backup[23]; strncpy( res_seq, backup + 25, sizeof(res_seq) - 1 ); res_seq[sizeof(res_seq) - 1] = '\0'; strncpy( s_x, backup + 30, sizeof(s_x) - 1 ); @@ -838,6 +885,24 @@ void Read_BGF( const char * const bgf_file, reax_system* system, control_params } } } + else if ( strncmp( tokens[0], "MOLCHARGE", 9 ) == 0 ) + { + assert( token_cnt == 4 ); + + system->molec_charge_constraint_ranges[2 * num_mcc] = sstrtol( tokens[1], __FILE__, __LINE__ ); + system->molec_charge_constraint_ranges[2 * num_mcc + 1] = sstrtol( tokens[2], __FILE__, __LINE__ ); + system->molec_charge_constraints[num_mcc] = sstrtod( tokens[3], __FILE__, __LINE__ ); + +#if defined(DEBUG_FOCUS) + fprintf( stderr, + "[INFO] num_mcc = %d, mcc = %f, mcc_range = (%d, %d)\n", num_mcc, + system->molec_charge_constraints[num_mcc], + system->molec_charge_constraint_ranges[2 * num_mcc], + system->molec_charge_constraint_ranges[2 * num_mcc + 1] ); +#endif + + ++num_mcc; + } /* clear previous input line */ line[0] = '\0'; diff --git a/sPuReMD/src/grid.c b/sPuReMD/src/grid.c index 25f9591c29d6625cb0bb587c8d79b15313040bc3..ad4e4fb6feff108d44825fb9bd4f86c905c06cae 100644 --- a/sPuReMD/src/grid.c +++ b/sPuReMD/src/grid.c @@ -26,7 +26,7 @@ #include "vector.h" -static int Estimate_GCell_Population( reax_system* system ) +static int Estimate_GCell_Population( reax_system * const system ) { int i, j, k, l; int max_atoms; @@ -69,7 +69,7 @@ static int Estimate_GCell_Population( reax_system* system ) } -static void Allocate_Space_for_Grid( reax_system *system, int alloc ) +static void Allocate_Space_for_Grid( reax_system * const system, int alloc ) { int i, j, k, l, max_atoms; grid *g; @@ -256,7 +256,7 @@ static void Allocate_Space_for_Grid( reax_system *system, int alloc ) } -static void Deallocate_Grid_Space( grid *g ) +static void Deallocate_Grid_Space( grid * const g ) { int i, j, k; @@ -305,7 +305,7 @@ static void Deallocate_Grid_Space( grid *g ) } -static inline int Shift( int p, int dp, int dim, grid *g ) +static inline int Shift( int p, int dp, int dim, grid const * const g ) { int dim_len, newp; @@ -339,7 +339,7 @@ static inline int Shift( int p, int dp, int dim, grid *g ) /* finds the closest point between two grid cells denoted by c1 and c2. * periodic boundary conditions are taken into consideration as well. */ -static void Find_Closest_Point( grid *g, int c1x, int c1y, int c1z, +static void Find_Closest_Point( grid const * const g, int c1x, int c1y, int c1z, int c2x, int c2y, int c2z, rvec closest_point ) { int i, d; @@ -385,7 +385,7 @@ static void Find_Closest_Point( grid *g, int c1x, int c1y, int c1z, } -static void Find_Neighbor_Grid_Cells( grid *g ) +static void Find_Neighbor_Grid_Cells( grid * const g ) { int i, j, k; int di, dj, dk; @@ -460,7 +460,7 @@ static void Find_Neighbor_Grid_Cells( grid *g ) } -void Setup_Grid( reax_system* system ) +void Setup_Grid( reax_system * const system ) { int d, alloc; grid *g; @@ -530,7 +530,7 @@ void Setup_Grid( reax_system* system ) } -void Update_Grid( reax_system* system ) +void Update_Grid( reax_system * const system ) { int d, i, j, k, x, y, z, itr; ivec ncell; @@ -614,7 +614,7 @@ void Update_Grid( reax_system* system ) } -void Bin_Atoms( reax_system* system, static_storage *workspace ) +void Bin_Atoms( reax_system * const system, static_storage * const workspace ) { int i, j, k, l; int max_atoms; @@ -666,7 +666,7 @@ void Bin_Atoms( reax_system* system, static_storage *workspace ) } -void Finalize_Grid( reax_system* system ) +void Finalize_Grid( reax_system * const system ) { if ( system->g.allocated == TRUE ) { @@ -675,7 +675,7 @@ void Finalize_Grid( reax_system* system ) } -static inline void reax_atom_Copy( reax_atom *dest, reax_atom *src ) +static void reax_atom_Copy( reax_atom * const dest, reax_atom * const src ) { dest->type = src->type; strncpy( dest->name, src->name, sizeof(dest->name) - 1 ); @@ -691,9 +691,10 @@ static inline void reax_atom_Copy( reax_atom *dest, reax_atom *src ) } -static void Copy_Storage( reax_system *system, static_storage *workspace, - control_params *control, int top, int old_id, int old_type, int *num_H, - real **v, real **s, real **t, int *orig_id, rvec *f_old ) +static void Copy_Storage( reax_system const * const system,static_storage * const workspace, + control_params const * const control, int top, int old_id, int old_type, + int * const num_H, real ** const v, real ** const s, real ** const t, + int * const orig_id, rvec * const f_old ) { int i; @@ -726,7 +727,8 @@ static void Copy_Storage( reax_system *system, static_storage *workspace, } -static void Free_Storage( static_storage *workspace, control_params * control ) +static void Free_Storage( static_storage * const workspace, + control_params const * const control ) { int i; @@ -759,8 +761,9 @@ static void Assign_New_Storage( static_storage *workspace, } -void Cluster_Atoms( reax_system *system, static_storage *workspace, - control_params *control ) +/* Reorder atom list to improve cache performance */ +void Reorder_Atoms( reax_system * const system, static_storage * const workspace, + control_params const * const control ) { int i, j, k, l, top, old_id, num_H; reax_atom *old_atom, *new_atoms; @@ -774,23 +777,23 @@ void Cluster_Atoms( reax_system *system, static_storage *workspace, top = 0; g = &system->g; - new_atoms = scalloc( system->N, sizeof(reax_atom), "Cluster_Atoms::new_atoms" ); - orig_id = scalloc( system->N, sizeof(int), "Cluster_Atoms::orig_id" ); - f_old = scalloc( system->N, sizeof(rvec), "Cluster_Atoms::f_old" ); + new_atoms = scalloc( system->N, sizeof(reax_atom), "Reorder_Atoms::new_atoms" ); + orig_id = scalloc( system->N, sizeof(int), "Reorder_Atoms::orig_id" ); + f_old = scalloc( system->N, sizeof(rvec), "Reorder_Atoms::f_old" ); - s = scalloc( 5, sizeof(real *), "Cluster_Atoms::s" ); - t = scalloc( 5, sizeof(real *), "Cluster_Atoms::t" ); + s = scalloc( 5, sizeof(real *), "Reorder_Atoms::s" ); + t = scalloc( 5, sizeof(real *), "Reorder_Atoms::t" ); for ( i = 0; i < 5; ++i ) { - s[i] = scalloc( system->N_cm, sizeof(real), "Cluster_Atoms::s[i]" ); - t[i] = scalloc( system->N_cm, sizeof(real), "Cluster_Atoms::t[i]" ); + s[i] = scalloc( system->N_cm, sizeof(real), "Reorder_Atoms::s[i]" ); + t[i] = scalloc( system->N_cm, sizeof(real), "Reorder_Atoms::t[i]" ); } v = scalloc( control->cm_solver_restart + 1, sizeof(real *), - "Cluster_Atoms::v" ); + "Reorder_Atoms::v" ); for ( i = 0; i < control->cm_solver_restart + 1; ++i ) { - v[i] = scalloc( system->N_cm, sizeof(real), "Cluster_Atoms::v[i]" ); + v[i] = scalloc( system->N_cm, sizeof(real), "Reorder_Atoms::v[i]" ); } for ( i = 0; i < g->ncell[0]; i++ ) @@ -818,7 +821,7 @@ void Cluster_Atoms( reax_system *system, static_storage *workspace, } } - sfree( system->atoms, "Cluster_Atoms::system->atoms" ); + sfree( system->atoms, "Reorder_Atoms::system->atoms" ); Free_Storage( workspace, control ); system->atoms = new_atoms; diff --git a/sPuReMD/src/grid.h b/sPuReMD/src/grid.h index d7e9a1986af74e0568010d1650c3a53b4209e8c8..1be1a4d7a852145a4a34368635f5c51ee2ba2ce3 100644 --- a/sPuReMD/src/grid.h +++ b/sPuReMD/src/grid.h @@ -25,15 +25,16 @@ #include "reax_types.h" -void Setup_Grid( reax_system * ); +void Setup_Grid( reax_system * const ); -void Update_Grid( reax_system * ); +void Update_Grid( reax_system * const ); -void Bin_Atoms( reax_system *, static_storage * ); +void Bin_Atoms( reax_system * const, static_storage * const ); -void Finalize_Grid( reax_system * ); +void Finalize_Grid( reax_system * const ); -void Cluster_Atoms( reax_system *, static_storage *, control_params * ); +void Reorder_Atoms( reax_system * const, static_storage * const, + control_params const * const ); #endif diff --git a/sPuReMD/src/init_md.c b/sPuReMD/src/init_md.c index dd1b8291313824d2ef3cf944dd64af789d6eef48..7c9fc2e97302986609bd231604c77be11d58dd72 100644 --- a/sPuReMD/src/init_md.c +++ b/sPuReMD/src/init_md.c @@ -377,8 +377,16 @@ static void Init_Workspace( reax_system *system, control_params *control, system->N_cm_max = system->N_max; break; case EE_CM: - system->N_cm = system->N + 1; - system->N_cm_max = system->N_max + 1; + if ( system->num_molec_charge_constraints == 0 ) + { + system->N_cm = system->N + 1; + system->N_cm_max = system->N_max + 1; + } + else + { + system->N_cm = system->N + system->num_molec_charge_constraints; + system->N_cm_max = system->N_max + system->num_molec_charge_constraints; + } break; case ACKS2_CM: system->N_cm = 2 * system->N + 2; @@ -440,7 +448,17 @@ static void Init_Workspace( reax_system *system, control_params *control, workspace->b_s[i] = -system->reax_param.sbp[ system->atoms[i].type ].chi; } - workspace->b_s[system->N] = control->cm_q_net; + if ( system->num_molec_charge_constraints == 0 ) + { + workspace->b_s[system->N] = control->cm_q_net; + } + else + { + for ( i = 0; i < system->num_molec_charge_constraints; ++i ) + { + workspace->b_s[system->N + i] = system->molec_charge_constraints[i]; + } + } break; case ACKS2_CM: @@ -796,7 +814,7 @@ static void Init_Lists( reax_system *system, control_params *control, lists[FAR_NBRS]->n = system->N; } - Generate_Neighbor_Lists( system, control, data, workspace, lists, out_control ); + Generate_Neighbor_Lists( system, control, data, workspace, lists ); Htop = 0; hb_top = scalloc( system->N, sizeof(int), "Init_Lists::hb_top" ); @@ -1339,6 +1357,15 @@ static void Finalize_System( reax_system *system, control_params *control, system->prealloc_allocated = FALSE; system->ffield_params_allocated = FALSE; + if ( system->max_num_molec_charge_constraints > 0 ) + { + sfree( system->molec_charge_constraints, "Read_BGF::molec_charge_constraints" ); + sfree( system->molec_charge_constraint_ranges, "Read_BGF::molec_charge_constraint_ranges" ); + } + + system->max_num_molec_charge_constraints = 0; + system->num_molec_charge_constraints = 0; + reax = &system->reax_param; Finalize_Grid( system ); diff --git a/sPuReMD/src/integrate.c b/sPuReMD/src/integrate.c index f23591a31afc1b6a7152e0812072a4df7e6d46dd..23e725ba35e7bcae684bfdafa3bc5f24495e7cb2 100644 --- a/sPuReMD/src/integrate.c +++ b/sPuReMD/src/integrate.c @@ -67,8 +67,7 @@ void Velocity_Verlet_NVE( reax_system *system, control_params *control, if ( renbr == TRUE ) { - Generate_Neighbor_Lists( system, control, data, workspace, - lists, out_control ); + Generate_Neighbor_Lists( system, control, data, workspace, lists ); } Compute_Forces( system, control, data, workspace, lists, out_control, FALSE ); @@ -119,7 +118,7 @@ void Velocity_Verlet_Berendsen_NVT( reax_system* system, if ( renbr == TRUE ) { - Generate_Neighbor_Lists( system, control, data, workspace, lists, out_control ); + Generate_Neighbor_Lists( system, control, data, workspace, lists ); } Compute_Forces( system, control, data, workspace, @@ -208,8 +207,7 @@ void Velocity_Verlet_Nose_Hoover_NVT_Klein( reax_system* system, control_params* if ( renbr == TRUE ) { - Generate_Neighbor_Lists( system, control, data, workspace, - lists, out_control ); + Generate_Neighbor_Lists( system, control, data, workspace, lists ); } /* Calculate Forces at time (t + dt) */ @@ -298,8 +296,8 @@ void Velocity_Verlet_Berendsen_Isotropic_NPT( reax_system* system, if ( renbr == TRUE ) { Update_Grid( system ); - Generate_Neighbor_Lists( system, control, data, workspace, - lists, out_control ); + + Generate_Neighbor_Lists( system, control, data, workspace, lists ); } Compute_Forces( system, control, data, workspace, lists, out_control, FALSE ); @@ -406,8 +404,8 @@ void Velocity_Verlet_Berendsen_Semi_Isotropic_NPT( reax_system* system, if ( renbr == TRUE ) { Update_Grid( system ); - Generate_Neighbor_Lists( system, control, data, workspace, - lists, out_control ); + + Generate_Neighbor_Lists( system, control, data, workspace, lists ); } Compute_Forces( system, control, data, workspace, lists, out_control, FALSE ); @@ -518,8 +516,8 @@ void Velocity_Verlet_Nose_Hoover_NVT( reax_system* system, control_params* contr fprintf(out_control->log, "reset-"); fflush( out_control->log ); - Generate_Neighbor_Lists( system, control, data, workspace, - lists, out_control ); + Generate_Neighbor_Lists( system, control, data, workspace, lists ); + fprintf(out_control->log, "nbrs-"); fflush( out_control->log ); @@ -622,8 +620,8 @@ void Velocity_Verlet_Isotropic_NPT( reax_system* system, control_params* control fprintf(out_control->log, "reset-"); fflush( out_control->log ); - Generate_Neighbor_Lists( system, control, data, workspace, - lists, out_control ); + Generate_Neighbor_Lists( system, control, data, workspace, lists ); + fprintf( out_control->log, "nbrs-" ); fflush( out_control->log ); diff --git a/sPuReMD/src/list.c b/sPuReMD/src/list.c index 4dd71e25922e02897ae59aba097684cfe93748f2..21dd6a69e64ad0e742f939e8d31440c684b1ccd0 100644 --- a/sPuReMD/src/list.c +++ b/sPuReMD/src/list.c @@ -49,18 +49,6 @@ void Make_List( int n, int n_max, int total_intrs, int type, reax_list* l ) switch ( type ) { - case TYP_VOID: - if ( l->total_intrs > 0 ) - { - l->v = smalloc( l->total_intrs * sizeof(void), - "Make_List::l->v" ); - } - else - { - l->v = NULL; - } - break; - case TYP_THREE_BODY: if ( l->total_intrs > 0 ) { @@ -174,13 +162,6 @@ void Delete_List( int type, reax_list* l ) switch ( type ) { - case TYP_VOID: - if ( l->v != NULL ) - { - sfree( l->v, "Delete_List::l->v" ); - } - break; - case TYP_THREE_BODY: if ( l->three_body_list != NULL ) { diff --git a/sPuReMD/src/lookup.c b/sPuReMD/src/lookup.c index a63b676372dcbb2b69f72f6ad058e4562b1d2e7f..a7b0b99c139e65034ea1591796649becb4a029bf 100644 --- a/sPuReMD/src/lookup.c +++ b/sPuReMD/src/lookup.c @@ -184,6 +184,7 @@ static void Complete_Cubic_Spline( const real *h, const real *f, real v0, real v } +#if defined(DEBUG_FOCUS) static void LR_Lookup( LR_lookup_table *t, real r, LR_data *y ) { int i; @@ -212,6 +213,7 @@ static void LR_Lookup( LR_lookup_table *t, real r, LR_data *y ) y->H = y->e_ele * EV_to_KCALpMOL / C_ELE; //y->H = ((t->H[i].d*dif + t->H[i].c)*dif + t->H[i].b)*dif + t->H[i].a; } +#endif void Make_LR_Lookup_Table( reax_system *system, control_params *control, diff --git a/sPuReMD/src/multi_body.c b/sPuReMD/src/multi_body.c index b9b1e67a52f6403393f5c40db2dec939724fa642..dae6b9039bae12ea1e35dc82ef90b924a0cbd492 100644 --- a/sPuReMD/src/multi_body.c +++ b/sPuReMD/src/multi_body.c @@ -40,7 +40,7 @@ void Atom_Energy( reax_system *system, control_params *control, 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_lp1, p_lp2, p_lp3; + real p_lp2, p_lp3; real p_ovun2, p_ovun3, p_ovun4, p_ovun5, p_ovun6, p_ovun7, p_ovun8; single_body_parameters *sbp_i; two_body_parameters *twbp; @@ -49,7 +49,6 @@ void Atom_Energy( reax_system *system, control_params *control, reax_list *bonds; bonds = lists[BONDS]; - p_lp1 = system->reax_param.gp.l[15]; p_lp3 = system->reax_param.gp.l[5]; p_ovun3 = system->reax_param.gp.l[32]; p_ovun4 = system->reax_param.gp.l[31]; diff --git a/sPuReMD/src/neighbors.c b/sPuReMD/src/neighbors.c index d44330b2f5c2baa300ff0b0a6da959e268d6e089..8d6f59966fa4b4052434fb434d418f647705ceca 100644 --- a/sPuReMD/src/neighbors.c +++ b/sPuReMD/src/neighbors.c @@ -48,7 +48,8 @@ typedef int (*find_far_neighbors_function)( rvec, rvec, int, int, simulation_box*, real, far_neighbor_data* ); -static void Choose_Neighbor_Counter( reax_system *system, control_params *control, +static void Choose_Neighbor_Counter( reax_system const * const system, + control_params const * const control, count_far_neighbors_function *Count_Far_Neighbors ) { if ( control->periodic_boundaries == TRUE ) @@ -75,7 +76,8 @@ static void Choose_Neighbor_Counter( reax_system *system, control_params *contro } -static void Choose_Neighbor_Finder( reax_system *system, control_params *control, +static void Choose_Neighbor_Finder( reax_system const * const system, + control_params const * const control, find_far_neighbors_function *Find_Far_Neighbors ) { if ( control->periodic_boundaries == TRUE ) @@ -103,7 +105,7 @@ static void Choose_Neighbor_Finder( reax_system *system, control_params *control #if defined(DEBUG_FOCUS) -static int compare_far_nbrs(const void *v1, const void *v2) +static int compare_far_nbrs( const void *v1, const void *v2 ) { return ((*(far_neighbor_data *)v1).nbr - (*(far_neighbor_data *)v2).nbr); } @@ -129,8 +131,10 @@ static inline real DistSqr_to_CP( rvec cp, rvec x ) } -int Estimate_Num_Neighbors( reax_system *system, control_params *control, - static_storage *workspace, reax_list **lists ) +/* Estimate the storage requirements for the far neighbor list */ +int Estimate_Num_Neighbors( reax_system * const system, + control_params const * const control, static_storage * const workspace, + reax_list ** const lists ) { int i, j, k, l, m, itr; int x, y, z; @@ -189,6 +193,11 @@ int Estimate_Num_Neighbors( reax_system *system, control_params *control, { atom2 = nbr_atoms[m]; +#if defined(QMMM) + if ( system->atoms[atom1].qmmm_mask == TRUE + || system->atoms[atom2].qmmm_mask == TRUE ) + { +#endif if ( atom1 >= atom2 ) { count = Count_Far_Neighbors( system->atoms[atom1].x, @@ -197,6 +206,9 @@ int Estimate_Num_Neighbors( reax_system *system, control_params *control, num_far += count; } +#if defined(QMMM) + } +#endif } } @@ -216,9 +228,10 @@ int Estimate_Num_Neighbors( reax_system *system, control_params *control, } -void Generate_Neighbor_Lists( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - reax_list **lists, output_controls *out_control ) +/* Generate the far neighbor list */ +void Generate_Neighbor_Lists( reax_system * const system, + control_params const * const control, simulation_data * const data, + static_storage * const workspace, reax_list ** const lists ) { int i, j, k, l, m, itr; int x, y, z; @@ -243,9 +256,15 @@ void Generate_Neighbor_Lists( reax_system *system, control_params *control, Bin_Atoms( system, workspace ); #if defined(REORDER_ATOMS) - //Cluster_Atoms( system, workspace, control ); + Reorder_Atoms( system, workspace, control ); #endif + for ( i = 0; i < far_nbrs->n; ++i ) + { + Set_Start_Index( i, 0, far_nbrs ); + Set_End_Index( i, 0, far_nbrs ); + } + /* for each cell in the grid along the 3 * Cartesian directions: (i, j, k) => (x, y, z) */ for ( i = 0; i < g->ncell[0]; i++ ) @@ -287,6 +306,11 @@ void Generate_Neighbor_Lists( reax_system *system, control_params *control, { atom2 = nbr_atoms[m]; +#if defined(QMMM) + if ( system->atoms[atom1].qmmm_mask == TRUE + || system->atoms[atom2].qmmm_mask == TRUE ) + { +#endif if ( atom1 >= atom2 ) { nbr_data = &far_nbrs->far_nbr_list[num_far]; @@ -297,6 +321,9 @@ void Generate_Neighbor_Lists( reax_system *system, control_params *control, num_far += count; } +#if defined(QMMM) + } +#endif } } diff --git a/sPuReMD/src/neighbors.h b/sPuReMD/src/neighbors.h index 06ee65dc93ab64a8cfbcfda7f66c519e572f9cce..45292a9dd34f47cf0250dd64af97d07704a3a1fa 100644 --- a/sPuReMD/src/neighbors.h +++ b/sPuReMD/src/neighbors.h @@ -25,11 +25,11 @@ #include "reax_types.h" -void Generate_Neighbor_Lists( reax_system*, control_params*, simulation_data*, - static_storage*, reax_list**, output_controls* ); +void Generate_Neighbor_Lists( reax_system * const, control_params const * const, + simulation_data * const, static_storage * const, reax_list ** const ); -int Estimate_Num_Neighbors( reax_system*, control_params*, - static_storage*, reax_list** ); +int Estimate_Num_Neighbors( reax_system * const, control_params const * const, + static_storage * const, reax_list ** const ); #endif diff --git a/sPuReMD/src/reax_types.h b/sPuReMD/src/reax_types.h index 74d03c2519cdd09d631af7ae4a1b9910fb068df1..4f006123ac87d560ac717a355fe45917764c12ea 100644 --- a/sPuReMD/src/reax_types.h +++ b/sPuReMD/src/reax_types.h @@ -48,8 +48,8 @@ //#define USE_REF_FORTRAN_EREAXFF_CONSTANTS /* constants defined in LAMMPS ReaxFF code (useful for comparisons) */ //#define USE_LAMMPS_REAXFF_CONSTANTS -/* enables reordering atoms after neighbor list generation (optimization) */ -#define REORDER_ATOMS +/* enables reordering atoms after neighbor list generation for improved cache performance */ +//#define REORDER_ATOMS /* enables support for small simulation boxes (i.e. a simulation box with any * dimension less than twice the Verlet list cutoff distance, vlist_cut), * which means multiple periodic images must be searched for interactions */ @@ -273,15 +273,14 @@ enum interaction_list_offets /* interaction type */ enum interaction_type { - TYP_VOID = 0, - TYP_THREE_BODY = 1, - TYP_BOND = 2, - TYP_HBOND = 3, - TYP_DBO = 4, - TYP_DDELTA = 5, - TYP_FAR_NEIGHBOR = 6, - TYP_NEAR_NEIGHBOR = 7, - TYP_N = 8, + TYP_THREE_BODY = 0, + TYP_BOND = 1, + TYP_HBOND = 2, + TYP_DBO = 3, + TYP_DDELTA = 4, + TYP_FAR_NEIGHBOR = 5, + TYP_NEAR_NEIGHBOR = 6, + TYP_N = 7, }; /* error codes for simulation termination */ @@ -878,6 +877,16 @@ struct reax_system int N_cm; /* max. dimension of the N x N sparse charge method matrix H across all simulations */ int N_cm_max; + /* molecular charge constraints + * NOTE: these constraints are currently only supported in BGF files using EEM */ + real *molec_charge_constraints; + /* molecular charge constraints encoded as pairs of 1-based atom numbers indicating a range of atoms + * NOTE: these constraints are currently only supported in BGF files using EEM */ + int *molec_charge_constraint_ranges; + /* num. of charge constraints on groups of atoms (i.e., molecules) */ + unsigned int num_molec_charge_constraints; + /* max. num. of charge constraints on groups of atoms (i.e., molecules) */ + unsigned int max_num_molec_charge_constraints; /* atom info */ reax_atom *atoms; /* atomic interaction parameters */ diff --git a/sPuReMD/src/spuremd.c b/sPuReMD/src/spuremd.c index efbb5ad1c5c752aa06322d4d49194ce220c54462..7658e1a93f860fab1279c8b8ea89e758d3b78531 100644 --- a/sPuReMD/src/spuremd.c +++ b/sPuReMD/src/spuremd.c @@ -232,9 +232,8 @@ void * setup( const char * const geo_file, const char * const ffield_file, Allocate_Top_Level_Structs( &spmd_handle ); Initialize_Top_Level_Structs( spmd_handle ); - /* note: assign here to avoid compiler warning - * of uninitialized usage in PreAllocate_Space */ spmd_handle->system->N_max = 0; + spmd_handle->system->max_num_molec_charge_constraints = 0; Read_Input_Files( geo_file, ffield_file, control_file, spmd_handle->system, spmd_handle->control, @@ -376,9 +375,6 @@ int simulate( const void * const handle ) Reset( spmd_handle->system, spmd_handle->control, spmd_handle->data, spmd_handle->workspace, spmd_handle->lists ); - Generate_Neighbor_Lists( spmd_handle->system, spmd_handle->control, spmd_handle->data, - spmd_handle->workspace, spmd_handle->lists, spmd_handle->out_control ); - Compute_Forces( spmd_handle->system, spmd_handle->control, spmd_handle->data, spmd_handle->workspace, spmd_handle->lists, spmd_handle->out_control, spmd_handle->realloc );