From 18df4177f56e2834e64f8ff651760c21f04caa7c Mon Sep 17 00:00:00 2001 From: "Kurt A. O'Hearn" <ohearnk@msu.edu> Date: Wed, 9 Jan 2019 15:52:45 -0500 Subject: [PATCH] PuReMD-old: clean-up and comment initialization optimizations. WIP: remove redundant computation of bonds list (not working for full far nbrs list). Improve hbond list computation for full far nbr list case. --- PuReMD/src/allocate.c | 2 - PuReMD/src/bond_orders.c | 166 +++- PuReMD/src/bond_orders.h | 22 +- PuReMD/src/forces.c | 1614 +++++++++++++++++++------------------- PuReMD/src/reax_types.h | 16 +- 5 files changed, 1008 insertions(+), 812 deletions(-) diff --git a/PuReMD/src/allocate.c b/PuReMD/src/allocate.c index 65474f1e..32b68ec1 100644 --- a/PuReMD/src/allocate.c +++ b/PuReMD/src/allocate.c @@ -145,7 +145,6 @@ void DeAllocate_Workspace( control_params *control, storage *workspace ) sfree( workspace->Clp, "Clp" ); sfree( workspace->vlpex, "vlpex" ); sfree( workspace->bond_mark, "bond_mark" ); - sfree( workspace->done_after, "done_after" ); /* CM storage */ sfree( workspace->Hdia_inv, "Hdia_inv" ); @@ -304,7 +303,6 @@ int Allocate_Workspace( reax_system *system, control_params *control, workspace->Clp = smalloc( total_real, "Clp", comm ); workspace->vlpex = smalloc( total_real, "vlpex", comm ); workspace->bond_mark = scalloc( total_cap, sizeof(int), "bond_mark", comm ); - workspace->done_after = scalloc( total_cap, sizeof(int), "done_after", comm ); /* CM storage */ workspace->Hdia_inv = scalloc( total_cap, sizeof(real), "Hdia_inv", comm ); diff --git a/PuReMD/src/bond_orders.c b/PuReMD/src/bond_orders.c index f01993b8..0c5950e5 100644 --- a/PuReMD/src/bond_orders.c +++ b/PuReMD/src/bond_orders.c @@ -662,6 +662,10 @@ void Add_dBond_to_Forces( int i, int pj, } +/* Compute the bond order term between atoms i and j, + * and if this term exceeds the cutoff bo_cut, then adds + * BOTH atoms the bonds list (i.e., compute term once + * and copy to avoid redundant computation) */ int BOp( storage *workspace, reax_list *bonds, real bo_cut, int i, int btop_i, int j, ivec *rel_box, real d, rvec *dvec, int far_nbr_list_format, single_body_parameters *sbp_i, @@ -683,21 +687,169 @@ int BOp( storage *workspace, reax_list *bonds, real bo_cut, C12 = twbp->p_bo1 * pow( d / twbp->r_s, twbp->p_bo2 ); BO_s = (1.0 + bo_cut) * exp( C12 ); } - else BO_s = C12 = 0.0; + else + { + C12 = 0.0; + BO_s = 0.0; + } if ( sbp_i->r_pi > 0.0 && sbp_j->r_pi > 0.0 ) { C34 = twbp->p_bo3 * pow( d / twbp->r_p, twbp->p_bo4 ); BO_pi = exp( C34 ); } - else BO_pi = C34 = 0.0; + else + { + C34 = 0.0; + BO_pi = 0.0; + } if ( sbp_i->r_pi_pi > 0.0 && sbp_j->r_pi_pi > 0.0 ) { C56 = twbp->p_bo5 * pow( d / twbp->r_pp, twbp->p_bo6 ); BO_pi2 = exp( C56 ); } - else BO_pi2 = C56 = 0.0; + else + { + C56 = 0.0; + BO_pi2 = 0.0; + } + + /* Initially BO values are the uncorrected ones, page 1 */ + BO = BO_s + BO_pi + BO_pi2; + + if ( BO >= bo_cut ) + { + /****** bonds i-j and j-i ******/ + ibond = &bonds->bond_list[btop_i]; + btop_j = End_Index( j, bonds ); + jbond = &bonds->bond_list[btop_j]; + + ibond->nbr = j; + ibond->d = d; + rvec_Copy( ibond->dvec, *dvec ); + ivec_Copy( ibond->rel_box, *rel_box ); + ibond->dbond_index = btop_i; + ibond->sym_index = btop_j; + jbond->nbr = i; + jbond->d = d; + rvec_Scale( jbond->dvec, -1.0, *dvec ); + ivec_Scale( jbond->rel_box, -1.0, *rel_box ); + jbond->dbond_index = btop_i; + jbond->sym_index = btop_i; + + Set_End_Index( j, btop_j + 1, bonds ); + + bo_ij = &ibond->bo_data; + bo_ij->BO = BO; + bo_ij->BO_s = BO_s; + bo_ij->BO_pi = BO_pi; + bo_ij->BO_pi2 = BO_pi2; + bo_ji = &jbond->bo_data; + bo_ji->BO = BO; + bo_ji->BO_s = BO_s; + bo_ji->BO_pi = BO_pi; + bo_ji->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, -1.0 * bo_ij->BO_s * Cln_BOp_s, ibond->dvec ); + rvec_Scale( bo_ij->dln_BOp_pi, -1.0 * bo_ij->BO_pi * Cln_BOp_pi, ibond->dvec ); + rvec_Scale( bo_ij->dln_BOp_pi2, -1.0 * bo_ij->BO_pi2 * Cln_BOp_pi2, ibond->dvec ); + rvec_Scale( bo_ji->dln_BOp_s, -1.0, bo_ij->dln_BOp_s ); + rvec_Scale( bo_ji->dln_BOp_pi, -1.0, bo_ij->dln_BOp_pi ); + rvec_Scale( bo_ji->dln_BOp_pi2, -1.0, 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, -1.0 * (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.0, 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 -= bo_cut; + bo_ij->BO -= bo_cut; + workspace->total_bond_order[i] += bo_ij->BO; //currently total_BOp + bo_ij->Cdbo = 0.0; + bo_ij->Cdbopi = 0.0; + bo_ij->Cdbopi2 = 0.0; + bo_ji->BO_s -= bo_cut; + bo_ji->BO -= bo_cut; + workspace->total_bond_order[j] += bo_ji->BO; //currently total_BOp + bo_ji->Cdbo = 0.0; + bo_ji->Cdbopi = 0.0; + bo_ji->Cdbopi2 = 0.0; + + return 1; + } + + return 0; +} + + +/* Compute the bond order term between atoms i and j, + * and if this term exceeds the cutoff bo_cut, then adds + * to the bond list according to the following convention: + * * if the far neighbor list is store in half format, + * add BOTH atoms to each other's portion of the bond list + * * if the far neighbor list is store in full format, + * add atom i to atom j's bonds list ONLY */ +int BOp_redundant( storage *workspace, reax_list *bonds, real bo_cut, + int i, int btop_i, int j, ivec *rel_box, real d, rvec *dvec, + int far_nbr_list_format, single_body_parameters *sbp_i, + single_body_parameters *sbp_j, two_body_parameters *twbp ) +{ + real r2, C12, C34, C56; + real Cln_BOp_s, Cln_BOp_pi, Cln_BOp_pi2; + real BO, BO_s, BO_pi, BO_pi2; + bond_data *ibond; + bond_order_data *bo_ij; + int btop_j; + bond_data *jbond; + bond_order_data *bo_ji; + + r2 = SQR(d); + + if ( sbp_i->r_s > 0.0 && sbp_j->r_s > 0.0 ) + { + C12 = twbp->p_bo1 * pow( d / twbp->r_s, twbp->p_bo2 ); + BO_s = (1.0 + bo_cut) * exp( C12 ); + } + else + { + C12 = 0.0; + BO_s = 0.0; + } + + if ( sbp_i->r_pi > 0.0 && sbp_j->r_pi > 0.0 ) + { + C34 = twbp->p_bo3 * pow( d / twbp->r_p, twbp->p_bo4 ); + BO_pi = exp( C34 ); + } + else + { + C34 = 0.0; + BO_pi = 0.0; + } + + if ( sbp_i->r_pi_pi > 0.0 && sbp_j->r_pi_pi > 0.0 ) + { + C56 = twbp->p_bo5 * pow( d / twbp->r_pp, twbp->p_bo6 ); + BO_pi2 = exp( C56 ); + } + else + { + C56 = 0.0; + BO_pi2 = 0.0; + } /* Initially BO values are the uncorrected ones, page 1 */ BO = BO_s + BO_pi + BO_pi2; @@ -730,14 +882,14 @@ int BOp( storage *workspace, reax_list *bonds, real bo_cut, Set_End_Index( j, btop_j + 1, bonds ); } - bo_ij = &( ibond->bo_data ); + bo_ij = &ibond->bo_data; bo_ij->BO = BO; bo_ij->BO_s = BO_s; bo_ij->BO_pi = BO_pi; bo_ij->BO_pi2 = BO_pi2; if ( far_nbr_list_format == HALF_LIST ) { - bo_ji = &( jbond->bo_data ); + bo_ji = &jbond->bo_data; bo_ji->BO = BO; bo_ji->BO_s = BO_s; bo_ji->BO_pi = BO_pi; @@ -750,7 +902,7 @@ int BOp( storage *workspace, reax_list *bonds, real bo_cut, 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 */ + * dln_BOp_xx/dr_i = -dln_BOp_xx/dr_j and all others are 0 */ rvec_Scale( bo_ij->dln_BOp_s, -1.0 * bo_ij->BO_s * Cln_BOp_s, ibond->dvec ); rvec_Scale( bo_ij->dln_BOp_pi, -1.0 * bo_ij->BO_pi * Cln_BOp_pi, ibond->dvec ); rvec_Scale( bo_ij->dln_BOp_pi2, -1.0 * bo_ij->BO_pi2 * Cln_BOp_pi2, ibond->dvec ); @@ -762,7 +914,7 @@ int BOp( storage *workspace, reax_list *bonds, real bo_cut, } /* Only dBOp wrt. dr_i is stored here, note that - dBOp/dr_i = -dBOp/dr_j and all others are 0 */ + * dBOp/dr_i = -dBOp/dr_j and all others are 0 */ rvec_Scale( bo_ij->dBOp, -1.0 * (bo_ij->BO_s * Cln_BOp_s + bo_ij->BO_pi * Cln_BOp_pi + bo_ij->BO_pi2 * Cln_BOp_pi2), ibond->dvec ); diff --git a/PuReMD/src/bond_orders.h b/PuReMD/src/bond_orders.h index fe142fb0..fcf4d71a 100644 --- a/PuReMD/src/bond_orders.h +++ b/PuReMD/src/bond_orders.h @@ -24,6 +24,7 @@ #include "reax_types.h" + typedef struct { real C1dbo, C2dbo, C3dbo; @@ -32,29 +33,42 @@ typedef struct real C1dDelta, C2dDelta, C3dDelta; } dbond_coefficients; + #ifdef TEST_FORCES void Get_dBO( reax_system*, reax_list**, int, int, real, rvec* ); + void Get_dBOpinpi2( reax_system*, reax_list**, - int, int, real, real, rvec*, rvec* ); + int, int, real, real, rvec*, rvec* ); void Add_dBO( reax_system*, reax_list**, int, int, real, rvec* ); + void Add_dBOpinpi2( reax_system*, reax_list**, - int, int, real, real, rvec*, rvec* ); + int, int, real, real, rvec*, rvec* ); void Add_dBO_to_Forces( reax_system*, reax_list**, int, int, real ); + void Add_dBOpinpi2_to_Forces( reax_system*, reax_list**, - int, int, real, real ); + int, int, real, real ); void Add_dDelta( reax_system*, reax_list**, int, real, rvec* ); + void Add_dDelta_to_Forces( reax_system *, reax_list**, int, real ); #endif void Add_dBond_to_Forces( int, int, storage*, reax_list** ); + void Add_dBond_to_Forces_NPT( int, int, simulation_data*, - storage*, reax_list** ); + storage*, reax_list** ); + int BOp( storage*, reax_list*, real, int, int, int, ivec*, real, rvec*, int, single_body_parameters*, single_body_parameters*, two_body_parameters* ); + +int BOp_redundant( storage*, reax_list*, real, int, int, int, ivec*, real, rvec*, + int, single_body_parameters*, single_body_parameters*, + two_body_parameters* ); + void BO( reax_system*, control_params*, simulation_data*, storage*, reax_list**, output_controls* ); + #endif diff --git a/PuReMD/src/forces.c b/PuReMD/src/forces.c index 7a5f4961..4588515d 100644 --- a/PuReMD/src/forces.c +++ b/PuReMD/src/forces.c @@ -20,39 +20,41 @@ ----------------------------------------------------------------------*/ #include "reax_types.h" + #if defined(PURE_REAX) -#include "forces.h" -#include "bond_orders.h" -#include "bonds.h" -#include "basic_comm.h" -#include "hydrogen_bonds.h" -#include "io_tools.h" -#include "list.h" -#include "lookup.h" -#include "multi_body.h" -#include "nonbonded.h" -#include "qEq.h" -#include "tool_box.h" -#include "torsion_angles.h" -#include "valence_angles.h" -#include "vector.h" + #include "forces.h" + #include "bond_orders.h" + #include "bonds.h" + #include "basic_comm.h" + #include "hydrogen_bonds.h" + #include "io_tools.h" + #include "list.h" + #include "lookup.h" + #include "multi_body.h" + #include "nonbonded.h" + #include "qEq.h" + #include "tool_box.h" + #include "torsion_angles.h" + #include "valence_angles.h" + #include "vector.h" #elif defined(LAMMPS_REAX) -#include "reax_forces.h" -#include "reax_bond_orders.h" -#include "reax_bonds.h" -#include "reax_basic_comm.h" -#include "reax_hydrogen_bonds.h" -#include "reax_io_tools.h" -#include "reax_list.h" -#include "reax_lookup.h" -#include "reax_multi_body.h" -#include "reax_nonbonded.h" -#include "reax_tool_box.h" -#include "reax_torsion_angles.h" -#include "reax_valence_angles.h" -#include "reax_vector.h" + #include "reax_forces.h" + #include "reax_bond_orders.h" + #include "reax_bonds.h" + #include "reax_basic_comm.h" + #include "reax_hydrogen_bonds.h" + #include "reax_io_tools.h" + #include "reax_list.h" + #include "reax_lookup.h" + #include "reax_multi_body.h" + #include "reax_nonbonded.h" + #include "reax_tool_box.h" + #include "reax_torsion_angles.h" + #include "reax_valence_angles.h" + #include "reax_vector.h" #endif + interaction_function Interaction_Functions[NUM_INTRS]; @@ -70,150 +72,13 @@ static void Dummy_Interaction( reax_system *system, control_params *control, } -void Init_Force_Functions( control_params *control ) -{ - Interaction_Functions[0] = &BO; - Interaction_Functions[1] = &Bonds; //Dummy_Interaction; - Interaction_Functions[2] = &Atom_Energy; //Dummy_Interaction; - Interaction_Functions[3] = &Valence_Angles; //Dummy_Interaction; - Interaction_Functions[4] = &Torsion_Angles; //Dummy_Interaction; - if ( control->hbond_cut > 0 ) - { - Interaction_Functions[5] = &Hydrogen_Bonds; - } - else - { - Interaction_Functions[5] = &Dummy_Interaction; - } - Interaction_Functions[6] = &Dummy_Interaction; //empty - Interaction_Functions[7] = &Dummy_Interaction; //empty - Interaction_Functions[8] = &Dummy_Interaction; //empty - Interaction_Functions[9] = &Dummy_Interaction; //empty -} - - -void Compute_Bonded_Forces( reax_system *system, control_params *control, - simulation_data *data, storage *workspace, - reax_list **lists, output_controls *out_control, - MPI_Comm comm ) -{ - int i; - - /* Mark beginning of a new timestep in bonded energy files */ -#if defined(TEST_ENERGY) - Debug_Marker_Bonded( out_control, data->step ); -#endif - - /* Implement all force calls as function pointers */ - for ( i = 0; i < NUM_INTRS; i++ ) - { -#if defined(DEBUG) - fprintf( stderr, "p%d: starting f%d\n", system->my_rank, i ); - MPI_Barrier( comm ); -#endif - (Interaction_Functions[i])( system, control, data, workspace, - lists, out_control ); -#if defined(DEBUG) - fprintf( stderr, "p%d: f%d done\n", system->my_rank, i ); - MPI_Barrier( comm ); -#endif - } -} - - -void Compute_NonBonded_Forces( reax_system *system, control_params *control, - simulation_data *data, storage *workspace, - reax_list **lists, output_controls *out_control, - MPI_Comm comm ) -{ - /* Mark beginning of a new timestep in nonbonded energy files */ -#if defined(TEST_ENERGY) - Debug_Marker_Nonbonded( out_control, data->step ); -#endif - - /* van der Waals and Coulomb interactions */ - if ( control->tabulate == 0 ) - vdW_Coulomb_Energy( system, control, data, workspace, - lists, out_control ); - else - Tabulated_vdW_Coulomb_Energy( system, control, data, workspace, - lists, out_control ); - -#if defined(DEBUG) - fprintf( stderr, "p%d: nonbonded forces done\n", system->my_rank ); - MPI_Barrier( comm ); -#endif -} - - -/* 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->bond_list[pj].nbr ) - { - if ( control->virial == 0 ) - { - Add_dBond_to_Forces( 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, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); - - 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, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); - Coll( system, mpi_data, workspace->f_vdw, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); - Coll( system, mpi_data, workspace->f_be, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); - Coll( system, mpi_data, workspace->f_lp, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); - Coll( system, mpi_data, workspace->f_ov, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); - Coll( system, mpi_data, workspace->f_un, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); - Coll( system, mpi_data, workspace->f_ang, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); - Coll( system, mpi_data, workspace->f_coa, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); - Coll( system, mpi_data, workspace->f_pen, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); - Coll( system, mpi_data, workspace->f_hb, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); - Coll( system, mpi_data, workspace->f_tor, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); - Coll( system, mpi_data, workspace->f_con, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); -#endif - -#endif -} - - -static void Validate_Lists( reax_system *system, storage *workspace, reax_list **lists, - int step, int n, int N, int numH, MPI_Comm comm ) +static 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); + realloc = &workspace->realloc; /* bond list */ if ( N > 0 ) @@ -229,19 +94,23 @@ static void Validate_Lists( reax_system *system, storage *workspace, reax_list * //workspace->realloc.bonds = 1; if ( i < N - 1 ) + { comp = Start_Index(i + 1, bonds); - else comp = bonds->num_intrs; + } + 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", + fprintf( stderr, "[ERROR] 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 ) { @@ -250,6 +119,7 @@ static void Validate_Lists( reax_system *system, storage *workspace, reax_list * for ( i = 0; i < n; ++i ) { Hindex = system->my_atoms[i].Hindex; + if ( Hindex > -1 ) { system->my_atoms[i].num_hbonds = @@ -260,48 +130,54 @@ static void Validate_Lists( reax_system *system, storage *workspace, reax_list * // workspace->realloc.hbonds = 1; if ( Hindex < numH - 1 ) - comp = Start_Index(Hindex + 1, hbonds); - else comp = hbonds->num_intrs; + { + 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", + fprintf(stderr, "[ERROR] 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 ); } } -/* - if ( Hindex > -1 ) - { - system->my_atoms[i].num_hbonds = - MAX( Num_Entries(Hindex, hbonds) * SAFER_ZONE, MIN_HBONDS ); -*/ + +// if ( Hindex > -1 ) +// { +// system->my_atoms[i].num_hbonds = +// 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; -/* + //TODO - if ( Hindex < system->n - 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( MPI_COMM_WORLD, INSUFFICIENT_MEMORY ); - } - } - -*/ - - - +// if ( Hindex < system->n - 1 ) +// { +// comp = Start_Index(Hindex + 1, hbonds); +// } +// else +// { +// comp = hbonds->num_intrs; +// } +// +// if ( End_Index(Hindex, hbonds) > comp ) +// { +// fprintf(stderr, "[ERROR] step%d-hbondchk failed: H=%d end(H)=%d str(H+1)=%d\n", +// step, Hindex, End_Index(Hindex, hbonds), comp ); +// MPI_Abort( MPI_COMM_WORLD, INSUFFICIENT_MEMORY ); +// } +// } } } } +/* Computes a charge matrix entry using the Taper function */ static real Compute_H( real r, real gamma, real *ctap ) { real taper, dr3gamij_1, dr3gamij_3; @@ -315,24 +191,32 @@ static real Compute_H( real r, real gamma, real *ctap ) taper = taper * r + ctap[0]; dr3gamij_1 = ( r * r * r + gamma ); - dr3gamij_3 = pow( dr3gamij_1 , 0.33333333333333 ); + dr3gamij_3 = pow( dr3gamij_1, 1.0 / 3.0 ); + return taper * EV_to_KCALpMOL / dr3gamij_3; } +/* Computes a charge matrix entry using the force tabulation + * (i.e., an arithmetic-reducing optimization) */ static real Compute_tabH( real r_ij, int ti, int tj ) { int r, tmin, tmax; real val, dif, base; LR_lookup_table *t; - tmin = MIN( ti, tj ); - tmax = MAX( ti, tj ); - t = &( LR[tmin][tmax] ); + tmin = MIN( ti, tj ); + tmax = MAX( ti, tj ); + t = &LR[tmin][tmax]; /* cubic spline interpolation */ r = (int)(r_ij * t->inv_dx); - if ( r == 0 ) ++r; + + 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 + @@ -343,6 +227,8 @@ static real Compute_tabH( real r_ij, int ti, int tj ) } +/* Compute the distances and displacement vectors for entries + * in the far neighbors list if it's a NOT re-neighboring step */ static void Init_Distance( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, MPI_Comm comm, mpi_datatypes *mpi_data ) @@ -364,7 +250,7 @@ static void Init_Distance( reax_system *system, control_params *control, start_i = Start_Index( i, far_nbrs ); end_i = End_Index( i, far_nbrs ); - /* update i-j distance for non-reneighboring steps */ + /* update distance and displacement vector between atoms i and j (i-j) */ for ( pj = start_i; pj < end_i; ++pj ) { j = far_nbrs->far_nbr_list.nbr[pj]; @@ -378,12 +264,13 @@ static void Init_Distance( reax_system *system, control_params *control, } } } - - } #if defined(NEUTRAL_TERRITORY) +/* Compute the charge matrix entries and store the matrix in half format + * using the far neighbors list (stored in full format) and according to + * the neutral territory communication method */ static void Init_CM_Half_NT( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, MPI_Comm comm, mpi_datatypes *mpi_data ) @@ -597,6 +484,9 @@ static void Init_CM_Half_NT( reax_system *system, control_params *control, } +/* Compute the charge matrix entries and store the matrix in full format + * using the far neighbors list (stored in full format) and according to + * the neutral territory communication method */ static void Init_CM_Full_NT( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, MPI_Comm comm, mpi_datatypes *mpi_data ) @@ -810,6 +700,9 @@ static void Init_CM_Full_NT( reax_system *system, control_params *control, #else +/* Compute the charge matrix entries and store the matrix in half format + * using the far neighbors list (stored in half format) and according to + * the full shell communication method */ static void Init_CM_Half_FS( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, MPI_Comm comm, mpi_datatypes *mpi_data ) @@ -894,6 +787,9 @@ static void Init_CM_Half_FS( reax_system *system, control_params *control, } +/* Compute the charge matrix entries and store the matrix in full format + * using the far neighbors list (stored in full format) and according to + * the full shell communication method */ static void Init_CM_Full_FS( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, MPI_Comm comm, mpi_datatypes *mpi_data ) @@ -975,6 +871,11 @@ static void Init_CM_Full_FS( reax_system *system, control_params *control, #endif +/* Compute entries of the bonds/hbonds lists and store the lists in full format + * using the far neighbors list (stored in half format) + * + * Note: this version does NOT contain an optimization to restrict the bond_mark + * array to at most the 3-hop neighborhood */ static void Init_Bond_Half( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, MPI_Comm comm, mpi_datatypes *mpi_data ) @@ -1002,8 +903,8 @@ static void Init_Bond_Half( reax_system *system, control_params *control, } 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 ); + /* put ghost atoms to an infinite distance (i.e., 1000) */ + workspace->bond_mark[i] = 1000; } num_bonds = 0; @@ -1098,8 +999,7 @@ static void Init_Bond_Half( reax_system *system, control_params *control, } /* uncorrected bond orders */ - if ( //(workspace->bond_mark[i] < 3 || workspace->bond_mark[j] < 3) && - BOp( workspace, bonds, control->bo_cut, + if ( BOp( workspace, bonds, control->bo_cut, i, btop_i, far_nbrs->far_nbr_list.nbr[pj], &far_nbrs->far_nbr_list.rel_box[pj], far_nbrs->far_nbr_list.d[pj], &far_nbrs->far_nbr_list.dvec[pj], far_nbrs->format, @@ -1149,6 +1049,8 @@ static void Init_Bond_Half( reax_system *system, control_params *control, } +/* Compute entries of the bonds/hbonds lists and store the lists in full format + * using the far neighbors list (stored in full format) */ static void Init_Bond_Full( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, MPI_Comm comm, mpi_datatypes *mpi_data ) @@ -1158,7 +1060,6 @@ static void Init_Bond_Full( reax_system *system, control_params *control, int type_i, type_j; int num_bonds, num_hbonds; int ihb, jhb, ihb_top; - int local; real cutoff; reax_list *far_nbrs, *bonds, *hbonds; single_body_parameters *sbp_i, *sbp_j; @@ -1172,95 +1073,52 @@ static void Init_Bond_Full( reax_system *system, control_params *control, far_nbrs = lists[FAR_NBRS]; bonds = lists[BONDS]; hbonds = lists[HBONDS]; - num_hbonds = 0; - for ( i = 0; i < system->N; ++i ) + /* hbonds */ + if ( control->hbond_cut > 0.0 ) { - 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 ); - - 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 == 1 ) + for ( i = 0; i < system->n; ++i ) { - if ( control->hbond_cut > 0 ) - { - ihb = sbp_i->p_hbond; - - if ( ihb == 1 ) - { - ihb_top = Start_Index( atom_i->Hindex, hbonds ); - } - else - { - ihb_top = -1; - } - } - } + atom_i = &system->my_atoms[i]; + type_i = atom_i->type; + sbp_i = &system->reax_param.sbp[type_i]; + ihb = sbp_i->p_hbond; - /* update i-j distance - check if j is within cutoff */ - for ( pj = start_i; pj < end_i; ++pj ) - { - j = far_nbrs->far_nbr_list.nbr[pj]; - atom_j = &system->my_atoms[j]; - - if ( far_nbrs->far_nbr_list.d[pj] <= cutoff ) + if ( ihb == 1 ) { - type_j = atom_j->type; - sbp_j = &system->reax_param.sbp[type_j]; + start_i = Start_Index( i, far_nbrs ); + end_i = End_Index( i, far_nbrs ); + ihb_top = Start_Index( atom_i->Hindex, hbonds ); - if ( local == 1 ) + /* check if j is within cutoff */ + for ( pj = start_i; pj < end_i; ++pj ) { - /* hydrogen bond lists */ - if ( control->hbond_cut > 0 - && (ihb == 1 || ihb == 2) - && far_nbrs->far_nbr_list.d[pj] <= control->hbond_cut ) + j = far_nbrs->far_nbr_list.nbr[pj]; + atom_j = &system->my_atoms[j]; + + if ( far_nbrs->far_nbr_list.d[pj] <= control->hbond_cut + && system->reax_param.sbp[atom_j->type].p_hbond == 2 ) { - // fprintf( stderr, "%d %d\n", atom1, atom2 ); - jhb = sbp_j->p_hbond; - - if ( ihb == 1 && jhb == 2 ) - { - hbonds->hbond_list[ihb_top].nbr = j; - hbonds->hbond_list[ihb_top].scl = 1; - hbonds->hbond_list[ihb_top].ptr = pj; - ++ihb_top; - ++num_hbonds; - } + hbonds->hbond_list[ihb_top].nbr = j; + hbonds->hbond_list[ihb_top].scl = 1; + hbonds->hbond_list[ihb_top].ptr = pj; + ++ihb_top; + ++num_hbonds; } } + Set_End_Index( atom_i->Hindex, ihb_top, hbonds ); } } - - if ( local == 1 && ihb == 1 ) - { - Set_End_Index( atom_i->Hindex, ihb_top, hbonds ); - } } - //Computing bond_mark + /* compute bond_mark */ push = 0; num_bonds = 0; btop_i = 0; bonds = lists[BONDS]; - q = smalloc( sizeof( int ) * (system->N - system->n), + q = smalloc( sizeof(int) * (system->N - system->n), "Init_Distance::q", MPI_COMM_WORLD ); for ( i = 0; i < system->n; ++i ) @@ -1269,11 +1127,11 @@ static void Init_Bond_Full( reax_system *system, control_params *control, } 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 ); + /* put ghost atoms to an infinite distance (i.e., 1000) */ + workspace->bond_mark[i] = 1000; } - //bonds that are directly connected to local atoms + /* bonds that are directly connected to local atoms */ for ( i = 0; i < system->n; ++i ) { atom_i = &system->my_atoms[i]; @@ -1287,21 +1145,30 @@ static void Init_Bond_Full( reax_system *system, control_params *control, { j = far_nbrs->far_nbr_list.nbr[pj]; atom_j = &system->my_atoms[j]; + if ( far_nbrs->far_nbr_list.d[pj] <= control->nonb_cut ) +// if ( i <= j && far_nbrs->far_nbr_list.d[pj] <= control->nonb_cut ) { 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, + if ( BOp_redundant( workspace, bonds, control->bo_cut, i, btop_i, far_nbrs->far_nbr_list.nbr[pj], &far_nbrs->far_nbr_list.rel_box[pj], far_nbrs->far_nbr_list.d[pj], &far_nbrs->far_nbr_list.dvec[pj], far_nbrs->format, sbp_i, sbp_j, twbp ) ) +// if ( BOp( workspace, bonds, control->bo_cut, +// i, btop_i, far_nbrs->far_nbr_list.nbr[pj], +// &far_nbrs->far_nbr_list.rel_box[pj], far_nbrs->far_nbr_list.d[pj], +// &far_nbrs->far_nbr_list.dvec[pj], far_nbrs->format, +// sbp_i, sbp_j, twbp ) ) { num_bonds += 2; ++btop_i; + /* if j is a non-local atom, push it on the queue + * to search for it's bonded neighbors later */ if ( workspace->bond_mark[j] == 1000 ) { workspace->bond_mark[j] = 1; @@ -1314,7 +1181,7 @@ static void Init_Bond_Full( reax_system *system, control_params *control, Set_End_Index( i, btop_i, bonds ); } - //bonds that are indirectly connected to local atoms + /* bonds that are indirectly connected to local atoms */ for ( k = 0; k < push; ++k ) { i = q[k]; @@ -1328,31 +1195,41 @@ static void Init_Bond_Full( reax_system *system, control_params *control, for ( pj = start_i; pj < end_i; ++pj ) { j = far_nbrs->far_nbr_list.nbr[pj]; - if( workspace->bond_mark[i] == 3 && workspace->bond_mark[j] == 1000 ) + + if ( workspace->bond_mark[i] == 3 + && workspace->bond_mark[j] == 1000 ) { continue; } + atom_j = &system->my_atoms[j]; + if ( far_nbrs->far_nbr_list.d[pj] <= control->bond_cut ) +// if ( i <= j && far_nbrs->far_nbr_list.d[pj] <= control->bond_cut ) { 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, + if ( BOp_redundant( workspace, bonds, control->bo_cut, i, btop_i, far_nbrs->far_nbr_list.nbr[pj], &far_nbrs->far_nbr_list.rel_box[pj], far_nbrs->far_nbr_list.d[pj], &far_nbrs->far_nbr_list.dvec[pj], far_nbrs->format, sbp_i, sbp_j, twbp ) ) +// if ( BOp( workspace, bonds, control->bo_cut, +// i, btop_i, far_nbrs->far_nbr_list.nbr[pj], +// &far_nbrs->far_nbr_list.rel_box[pj], far_nbrs->far_nbr_list.d[pj], +// &far_nbrs->far_nbr_list.dvec[pj], far_nbrs->format, +// sbp_i, sbp_j, twbp ) ) { num_bonds += 2; ++btop_i; if ( workspace->bond_mark[j] == 1000 ) { - workspace->bond_mark[j] = workspace->bond_mark[i] + 1; - if( workspace->bond_mark[j] < 4 ) + workspace->bond_mark[j] = workspace->bond_mark[i] + 1; + + if ( workspace->bond_mark[j] < 4 ) { q[ push++ ] = j; } @@ -1369,46 +1246,47 @@ static void Init_Bond_Full( reax_system *system, control_params *control, //neighborhood relationship with any local atoms //those atoms have their bond_mark value still //equal to 1000 - /*for ( i = system->n; i < system->N; ++i ) - { - if ( workspace->bond_mark[i] == 1000 ) - { - 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]; - start_i = Start_Index( i, far_nbrs ); - end_i = End_Index( i, far_nbrs ); +// for ( i = system->n; i < system->N; ++i ) +// { +// if ( workspace->bond_mark[i] == 1000 ) +// { +// 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]; +// start_i = Start_Index( i, far_nbrs ); +// end_i = End_Index( i, far_nbrs ); +// +// for ( pj = start_i; pj < end_i; ++pj ) +// { +// j = far_nbrs->far_nbr_list.nbr[pj]; +// atom_j = &system->my_atoms[j]; +// if ( far_nbrs->far_nbr_list.d[pj] <= control->bond_cut ) +// { +// 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, far_nbrs->far_nbr_list.nbr[pj], +// &far_nbrs->far_nbr_list.rel_box[pj], far_nbrs->far_nbr_list.d[pj], +// &far_nbrs->far_nbr_list.dvec[pj], far_nbrs->format, +// sbp_i, sbp_j, twbp ) ) +// { +// num_bonds += 2; +// ++btop_i; +// } +// } +// } +// +// Set_End_Index( i, btop_i, bonds ); +// } +// } - for ( pj = start_i; pj < end_i; ++pj ) - { - j = far_nbrs->far_nbr_list.nbr[pj]; - atom_j = &system->my_atoms[j]; - if ( far_nbrs->far_nbr_list.d[pj] <= control->bond_cut ) - { - 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, far_nbrs->far_nbr_list.nbr[pj], - &far_nbrs->far_nbr_list.rel_box[pj], far_nbrs->far_nbr_list.d[pj], - &far_nbrs->far_nbr_list.dvec[pj], far_nbrs->format, - sbp_i, sbp_j, twbp ) ) - { - num_bonds += 2; - ++btop_i; - } - } - } - - Set_End_Index( i, btop_i, bonds ); - } - }*/ workspace->realloc.num_bonds = num_bonds; sfree( q, "Init_Bond_Full::q" ); - for( i = 0; i < system->N; ++i ) + for ( i = 0; i < system->N; ++i ) { qsort( &bonds->bond_list[Start_Index(i, bonds)], Num_Entries(i, bonds), sizeof(bond_data), compare_bonds ); @@ -1456,490 +1334,633 @@ static void Init_Bond_Full( reax_system *system, control_params *control, } -void Init_Forces( reax_system *system, control_params *control, - simulation_data *data, storage *workspace, reax_list **lists, - output_controls *out_control, MPI_Comm comm, mpi_datatypes *mpi_data ) +void Init_Force_Functions( control_params *control ) { - double t_start, t_dist, t_cm, t_bond; - double timings[3], t_total[3]; - - t_start = MPI_Wtime( ); - - Init_Distance( system, control, data, workspace, lists, out_control, comm, mpi_data ); - - t_dist = MPI_Wtime( ); - -#if defined(NEUTRAL_TERRITORY) - if ( workspace->H->format == SYM_HALF_MATRIX ) - { - Init_CM_Half_NT( system, control, data, workspace, lists, out_control, comm, mpi_data ); - } - else - { - Init_CM_Full_NT( system, control, data, workspace, lists, out_control, comm, mpi_data ); - } -#else - if ( workspace->H->format == SYM_HALF_MATRIX ) - { - Init_CM_Half_FS( system, control, data, workspace, lists, out_control, comm, mpi_data ); - } - else - { - Init_CM_Full_FS( system, control, data, workspace, lists, out_control, comm, mpi_data ); - } -#endif - - t_cm = MPI_Wtime(); - - if ( lists[FAR_NBRS]->format == HALF_LIST ) + Interaction_Functions[0] = &BO; + Interaction_Functions[1] = &Bonds; //Dummy_Interaction; + Interaction_Functions[2] = &Atom_Energy; //Dummy_Interaction; + Interaction_Functions[3] = &Valence_Angles; //Dummy_Interaction; + Interaction_Functions[4] = &Torsion_Angles; //Dummy_Interaction; + if ( control->hbond_cut > 0.0 ) { - Init_Bond_Half( system, control, data, workspace, lists, out_control, comm, mpi_data ); + Interaction_Functions[5] = &Hydrogen_Bonds; } else { - Init_Bond_Full( system, control, data, workspace, lists, out_control, comm, mpi_data ); - } - - t_bond = MPI_Wtime(); - - timings[0] = t_dist - t_start; - timings[1] = t_cm - t_dist; - timings[2] = t_bond - t_cm; - - MPI_Reduce( timings, t_total, 3, MPI_DOUBLE, MPI_SUM, MASTER_NODE, mpi_data->world ); - - if ( system->my_rank == MASTER_NODE ) - { - data->timing.init_dist += t_total[0] / control->nprocs; - data->timing.init_cm += t_total[1] / control->nprocs; - data->timing.init_bond += t_total[2] / control->nprocs; - } - -} - - -/*void Init_Forces( reax_system *system, control_params *control, - simulation_data *data, storage *workspace, reax_list **lists, - output_controls *out_control, MPI_Comm comm, mpi_datatypes *mpi_data ) -{ - int i, j, pj; - int start_i, end_i; - int type_i, type_j; - int Htop, btop_i, num_bonds, num_hbonds; - int ihb, jhb, ihb_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; - reax_atom *atom_i, *atom_j; - int jhb_top; - int start_j, end_j; - int btop_j; -#if defined(NEUTRAL_TERRITORY) - int mark[6]; - int total_cnt[6]; - int bin[6]; - int total_sum[6]; - int nt_flag; -#endif - - 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 = 0; - renbr = (data->step - data->prev_steps) % control->reneighbor == 0; - -#if defined(NEUTRAL_TERRITORY) - nt_flag = 1; - if( renbr ) - { - for ( i = 0; i < 6; ++i ) - { - total_cnt[i] = 0; - bin[i] = 0; - total_sum[i] = 0; - } - - for ( i = system->n; i < system->N; ++i ) - { - atom_i = &system->my_atoms[i]; - - if( atom_i->nt_dir != -1 ) - { - total_cnt[ atom_i->nt_dir ]++; - } - } - - total_sum[0] = system->n; - for ( i = 1; i < 6; ++i ) - { - total_sum[i] = total_sum[i-1] + total_cnt[i-1]; - } - - for ( i = system->n; i < system->N; ++i ) - { - atom_i = &system->my_atoms[i]; - - if( atom_i->nt_dir != -1 ) - { - atom_i->pos = total_sum[ atom_i->nt_dir ] + bin[ atom_i->nt_dir ]; - bin[ atom_i->nt_dir ]++; - } - } - H->NT = total_sum[5] + total_cnt[5]; + Interaction_Functions[5] = &Dummy_Interaction; } + Interaction_Functions[6] = &Dummy_Interaction; //empty + Interaction_Functions[7] = &Dummy_Interaction; //empty + Interaction_Functions[8] = &Dummy_Interaction; //empty + Interaction_Functions[9] = &Dummy_Interaction; //empty +} - mark[0] = mark[1] = 1; - mark[2] = mark[3] = mark[4] = mark[5] = 2; -#endif - - 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); - - if ( far_nbrs->format == HALF_LIST ) - { - // start at end because other atoms - // can add to this atom's list (half-list) - btop_i = End_Index( i, bonds ); - } - else if ( far_nbrs->format == FULL_LIST ) - { - btop_i = Start_Index( i, bonds ); - } - sbp_i = &system->reax_param.sbp[type_i]; - - if ( i < system->n ) - { - local = 1; - cutoff = control->nonb_cut; - } -#if defined(NEUTRAL_TERRITORY) - else if ( atom_i->nt_dir != -1 ) - { - local = 2; - cutoff = control->nonb_cut; - nt_flag = 0; - } -#endif - else - { - local = 0; - cutoff = control->bond_cut; - } - - ihb = -1; - ihb_top = -1; - if ( local == 1 ) - { - 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 ) - { - if ( far_nbrs->format == HALF_LIST ) - { - // start at end because other atoms - // can add to this atom's list (half-list) - ihb_top = End_Index( atom_i->Hindex, hbonds ); - } - else if ( far_nbrs->format == FULL_LIST ) - { - ihb_top = Start_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 ) - { - j = far_nbrs->far_nbr_list.nbr[pj]; - atom_j = &system->my_atoms[j]; - - if ( renbr ) - { - if ( far_nbrs->far_nbr_list.d[pj] <= cutoff ) - flag = 1; - else - flag = 0; - } - else - { - far_nbrs->far_nbr_list.dvec[pj][0] = atom_j->x[0] - atom_i->x[0]; - far_nbrs->far_nbr_list.dvec[pj][1] = atom_j->x[1] - atom_i->x[1]; - far_nbrs->far_nbr_list.dvec[pj][2] = atom_j->x[2] - atom_i->x[2]; - far_nbrs->far_nbr_list.d[pj] = rvec_Norm_Sqr( far_nbrs->far_nbr_list.dvec[pj] ); - - if ( far_nbrs->far_nbr_list.d[pj] <= SQR(cutoff) ) - { - far_nbrs->far_nbr_list.d[pj] = sqrt( far_nbrs->far_nbr_list.d[pj] ); - flag = 1; - } - else - { - flag = 0; - } - } - - if ( flag ) - { - type_j = atom_j->type; - r_ij = far_nbrs->far_nbr_list.d[pj]; - sbp_j = &system->reax_param.sbp[type_j]; - twbp = &system->reax_param.tbp[type_i][type_j]; - - if ( local == 1 ) - { - // H matrix entry -#if defined(NEUTRAL_TERRITORY) - if ( atom_j->nt_dir > 0 || (j < system->n - && (H->format == SYM_FULL_MATRIX - || (H->format == SYM_HALF_MATRIX && i < j))) ) - { - if( j < system->n ) - { - H->entries[Htop].j = j; - } - else - { - H->entries[Htop].j = atom_j->pos; - } - - 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; - } -#else - if ( (far_nbrs->format == HALF_LIST - && (j < system->n || atom_i->orig_id < atom_j->orig_id)) - || far_nbrs->format == FULL_LIST ) - { - H->entries[Htop].j = j; - - 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; - } -#endif - - // hydrogen bond lists - if ( control->hbond_cut > 0.0 - && (ihb == 1 || ihb == 2) - && far_nbrs->far_nbr_list.d[pj] <= control->hbond_cut ) - { - // fprintf( stderr, "%d %d\n", atom1, atom2 ); - jhb = sbp_j->p_hbond; - if ( ihb == 1 && jhb == 2 ) - { - hbonds->hbond_list[ihb_top].nbr = j; - hbonds->hbond_list[ihb_top].scl = 1; - hbonds->hbond_list[ihb_top].ptr = pj; - ++ihb_top; - ++num_hbonds; - } - // only add to list for local j (far nbrs is half-list) - else if ( far_nbrs->format == HALF_LIST - && (j < system->n && ihb == 2 && jhb == 1) ) - { - jhb_top = End_Index( atom_j->Hindex, hbonds ); - hbonds->hbond_list[jhb_top].nbr = i; - hbonds->hbond_list[jhb_top].scl = -1; - hbonds->hbond_list[jhb_top].ptr = pj; - Set_End_Index( atom_j->Hindex, jhb_top + 1, hbonds ); - ++num_hbonds; - } - } - } -#if defined(NEUTRAL_TERRITORY) - else if ( local == 2 ) - { - // H matrix entry - if( ( atom_j->nt_dir != -1 && mark[atom_i->nt_dir] != mark[atom_j->nt_dir] - && ( H->format == SYM_FULL_MATRIX - || (H->format == SYM_HALF_MATRIX && atom_i->pos < atom_j->pos))) - || ( j < system->n && atom_i->nt_dir != 0 && H->format == SYM_FULL_MATRIX )) - { - if( !nt_flag ) - { - nt_flag = 1; - H->start[atom_i->pos] = Htop; - } - - if( j < system->n ) - { - H->entries[Htop].j = j; - } - else - { - H->entries[Htop].j = atom_j->pos; - } - - 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; - } - } +void Compute_Bonded_Forces( reax_system *system, control_params *control, + simulation_data *data, storage *workspace, reax_list **lists, + output_controls *out_control, MPI_Comm comm ) +{ + int i; + + /* Mark beginning of a new timestep in bonded energy files */ +#if defined(TEST_ENERGY) + Debug_Marker_Bonded( out_control, data->step ); #endif - // uncorrected bond orders - if ( //(workspace->bond_mark[i] < 3 || workspace->bond_mark[j] < 3) && - far_nbrs->far_nbr_list.d[pj] <= control->bond_cut - && BOp( workspace, bonds, control->bo_cut, - i, btop_i, far_nbrs->far_nbr_list.nbr[pj], - &far_nbrs->far_nbr_list.rel_box[pj], far_nbrs->far_nbr_list.d[pj], - &far_nbrs->far_nbr_list.dvec[pj], far_nbrs->format, - sbp_i, sbp_j, twbp ) ) - { - num_bonds += 2; - ++btop_i; + /* Implement all force calls as function pointers */ + for ( i = 0; i < NUM_INTRS; i++ ) + { +#if defined(DEBUG) + fprintf( stderr, "p%d: starting f%d\n", system->my_rank, i ); + MPI_Barrier( comm ); +#endif - 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; - } - } - } - } + (Interaction_Functions[i])( system, control, data, workspace, + lists, out_control ); - Set_End_Index( i, btop_i, bonds ); - if ( local == 1 ) - { - H->end[i] = Htop; - if ( ihb == 1 ) - Set_End_Index( atom_i->Hindex, ihb_top, hbonds ); - } -#if defined(NEUTRAL_TERRITORY) - else if ( local == 2 ) - { - if( nt_flag ) - { - H->end[atom_i->pos] = Htop; - } - else - { - H->start[atom_i->pos] = 0; - H->end[atom_i->pos] = 0; - } - } +#if defined(DEBUG) + fprintf( stderr, "p%d: f%d done\n", system->my_rank, i ); + MPI_Barrier( comm ); #endif } +} - if ( far_nbrs->format == FULL_LIST ) + +void Compute_NonBonded_Forces( reax_system *system, control_params *control, + simulation_data *data, storage *workspace, reax_list **lists, + output_controls *out_control, MPI_Comm comm ) +{ + /* Mark beginning of a new timestep in nonbonded energy files */ +#if defined(TEST_ENERGY) + Debug_Marker_Nonbonded( out_control, data->step ); +#endif + + /* van der Waals and Coulomb interactions */ + if ( control->tabulate == 0 ) + { + vdW_Coulomb_Energy( system, control, data, workspace, + lists, out_control ); + } + else { + Tabulated_vdW_Coulomb_Energy( system, control, data, workspace, + lists, out_control ); + } - for( i = 0; i < system->N; ++i ) - qsort( &bonds->bond_list[Start_Index(i, bonds)], - Num_Entries(i, bonds), sizeof(bond_data), compare_bonds ); +#if defined(DEBUG) + fprintf( stderr, "p%d: nonbonded forces done\n", system->my_rank ); + MPI_Barrier( comm ); +#endif +} - // set sym_index for bonds list (far_nbrs full list) - for ( i = 0; i < system->N; ++i ) - { - start_i = Start_Index( i, bonds ); - end_i = End_Index( i, bonds ); - for ( btop_i = start_i; btop_i < end_i; ++btop_i ) - { - j = bonds->bond_list[btop_i].nbr; - start_j = Start_Index( j, bonds ); - end_j = End_Index( j, 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, storage *workspace, + reax_list **lists, mpi_datatypes *mpi_data ) +{ + int i, pj; + reax_list *bonds; - for ( btop_j = start_j; btop_j < end_j; ++btop_j ) + 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->bond_list[pj].nbr ) + { + if ( control->virial == 0 ) { - if ( bonds->bond_list[btop_j].nbr == i ) - { - bonds->bond_list[btop_i].sym_index = btop_j; - break; - } + Add_dBond_to_Forces( i, pj, workspace, lists ); + } + else + { + Add_dBond_to_Forces_NPT( i, pj, data, workspace, lists ); } } } } -#if defined(DEBUG) - Print_Sparse_Matrix2( system, H, NULL ); -#endif + //Print_Total_Force( system, data, workspace ); - workspace->realloc.Htop = Htop; - workspace->realloc.num_bonds = num_bonds; - workspace->realloc.num_hbonds = num_hbonds; +#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, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); -#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 ); + 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, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); + Coll( system, mpi_data, workspace->f_vdw, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); + Coll( system, mpi_data, workspace->f_be, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); + Coll( system, mpi_data, workspace->f_lp, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); + Coll( system, mpi_data, workspace->f_ov, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); + Coll( system, mpi_data, workspace->f_un, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); + Coll( system, mpi_data, workspace->f_ang, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); + Coll( system, mpi_data, workspace->f_coa, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); + Coll( system, mpi_data, workspace->f_pen, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); + Coll( system, mpi_data, workspace->f_hb, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); + Coll( system, mpi_data, workspace->f_tor, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); + Coll( system, mpi_data, workspace->f_con, RVEC_PTR_TYPE, mpi_data->mpi_rvec ); #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, storage *workspace, reax_list **lists, + output_controls *out_control, MPI_Comm comm, mpi_datatypes *mpi_data ) +{ + double t_start, t_dist, t_cm, t_bond; + double timings[3], t_total[3]; + + t_start = MPI_Wtime( ); + + Init_Distance( system, control, data, workspace, lists, out_control, comm, mpi_data ); + + t_dist = MPI_Wtime( ); + +#if defined(NEUTRAL_TERRITORY) + if ( workspace->H->format == SYM_HALF_MATRIX ) + { + Init_CM_Half_NT( system, control, data, workspace, lists, out_control, comm, mpi_data ); + } + else + { + Init_CM_Full_NT( system, control, data, workspace, lists, out_control, comm, mpi_data ); + } +#else + if ( workspace->H->format == SYM_HALF_MATRIX ) + { + Init_CM_Half_FS( system, control, data, workspace, lists, out_control, comm, mpi_data ); + } + else + { + Init_CM_Full_FS( system, control, data, workspace, lists, out_control, comm, mpi_data ); + } +#endif + + t_cm = MPI_Wtime(); + + if ( lists[FAR_NBRS]->format == HALF_LIST ) + { + Init_Bond_Half( system, control, data, workspace, lists, out_control, comm, mpi_data ); + } + else + { + Init_Bond_Full( system, control, data, workspace, lists, out_control, comm, mpi_data ); + } + + t_bond = MPI_Wtime(); + + timings[0] = t_dist - t_start; + timings[1] = t_cm - t_dist; + timings[2] = t_bond - t_cm; + + MPI_Reduce( timings, t_total, 3, MPI_DOUBLE, MPI_SUM, MASTER_NODE, mpi_data->world ); + + if ( system->my_rank == MASTER_NODE ) + { + data->timing.init_dist += t_total[0] / control->nprocs; + data->timing.init_cm += t_total[1] / control->nprocs; + data->timing.init_bond += t_total[2] / control->nprocs; + } + +} + + +//void Init_Forces( reax_system *system, control_params *control, +// simulation_data *data, storage *workspace, reax_list **lists, +// output_controls *out_control, MPI_Comm comm, mpi_datatypes *mpi_data ) +//{ +// int i, j, pj; +// int start_i, end_i; +// int type_i, type_j; +// int Htop, btop_i, num_bonds, num_hbonds; +// int ihb, jhb, ihb_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; +// reax_atom *atom_i, *atom_j; +// int jhb_top; +// int start_j, end_j; +// int btop_j; +//#if defined(NEUTRAL_TERRITORY) +// int mark[6]; +// int total_cnt[6]; +// int bin[6]; +// int total_sum[6]; +// int nt_flag; +//#endif +// +// 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 ) +// { +// /* put ghost atoms to an infinite distance (i.e., 1000) */ +// workspace->bond_mark[i] = 1000; +// } +// +// H = workspace->H; +// H->n = system->n; +// Htop = 0; +// num_bonds = 0; +// num_hbonds = 0; +// btop_i = 0; +// renbr = (data->step - data->prev_steps) % control->reneighbor == 0; +// +//#if defined(NEUTRAL_TERRITORY) +// nt_flag = 1; +// if( renbr ) +// { +// for ( i = 0; i < 6; ++i ) +// { +// total_cnt[i] = 0; +// bin[i] = 0; +// total_sum[i] = 0; +// } +// +// for ( i = system->n; i < system->N; ++i ) +// { +// atom_i = &system->my_atoms[i]; +// +// if( atom_i->nt_dir != -1 ) +// { +// total_cnt[ atom_i->nt_dir ]++; +// } +// } +// +// total_sum[0] = system->n; +// for ( i = 1; i < 6; ++i ) +// { +// total_sum[i] = total_sum[i-1] + total_cnt[i-1]; +// } +// +// for ( i = system->n; i < system->N; ++i ) +// { +// atom_i = &system->my_atoms[i]; +// +// if( atom_i->nt_dir != -1 ) +// { +// atom_i->pos = total_sum[ atom_i->nt_dir ] + bin[ atom_i->nt_dir ]; +// bin[ atom_i->nt_dir ]++; +// } +// } +// H->NT = total_sum[5] + total_cnt[5]; +// } +// +// mark[0] = mark[1] = 1; +// mark[2] = mark[3] = mark[4] = mark[5] = 2; +//#endif +// +// 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); +// +// if ( far_nbrs->format == HALF_LIST ) +// { +// // start at end because other atoms +// // can add to this atom's list (half-list) +// btop_i = End_Index( i, bonds ); +// } +// else if ( far_nbrs->format == FULL_LIST ) +// { +// btop_i = Start_Index( i, bonds ); +// } +// sbp_i = &system->reax_param.sbp[type_i]; +// +// if ( i < system->n ) +// { +// local = 1; +// cutoff = control->nonb_cut; +// } +//#if defined(NEUTRAL_TERRITORY) +// else if ( atom_i->nt_dir != -1 ) +// { +// local = 2; +// cutoff = control->nonb_cut; +// nt_flag = 0; +// } +//#endif +// else +// { +// local = 0; +// cutoff = control->bond_cut; +// } +// +// ihb = -1; +// ihb_top = -1; +// if ( local == 1 ) +// { +// 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 ) +// { +// if ( far_nbrs->format == HALF_LIST ) +// { +// // start at end because other atoms +// // can add to this atom's list (half-list) +// ihb_top = End_Index( atom_i->Hindex, hbonds ); +// } +// else if ( far_nbrs->format == FULL_LIST ) +// { +// ihb_top = Start_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 ) +// { +// j = far_nbrs->far_nbr_list.nbr[pj]; +// atom_j = &system->my_atoms[j]; +// +// if ( renbr ) +// { +// if ( far_nbrs->far_nbr_list.d[pj] <= cutoff ) +// flag = 1; +// else +// flag = 0; +// } +// else +// { +// far_nbrs->far_nbr_list.dvec[pj][0] = atom_j->x[0] - atom_i->x[0]; +// far_nbrs->far_nbr_list.dvec[pj][1] = atom_j->x[1] - atom_i->x[1]; +// far_nbrs->far_nbr_list.dvec[pj][2] = atom_j->x[2] - atom_i->x[2]; +// far_nbrs->far_nbr_list.d[pj] = rvec_Norm_Sqr( far_nbrs->far_nbr_list.dvec[pj] ); +// +// if ( far_nbrs->far_nbr_list.d[pj] <= SQR(cutoff) ) +// { +// far_nbrs->far_nbr_list.d[pj] = sqrt( far_nbrs->far_nbr_list.d[pj] ); +// flag = 1; +// } +// else +// { +// flag = 0; +// } +// } +// +// if ( flag ) +// { +// type_j = atom_j->type; +// r_ij = far_nbrs->far_nbr_list.d[pj]; +// sbp_j = &system->reax_param.sbp[type_j]; +// twbp = &system->reax_param.tbp[type_i][type_j]; +// +// if ( local == 1 ) +// { +// // H matrix entry +//#if defined(NEUTRAL_TERRITORY) +// if ( atom_j->nt_dir > 0 || (j < system->n +// && (H->format == SYM_FULL_MATRIX +// || (H->format == SYM_HALF_MATRIX && i < j))) ) +// { +// if( j < system->n ) +// { +// H->entries[Htop].j = j; +// } +// else +// { +// H->entries[Htop].j = atom_j->pos; +// } +// +// 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; +// } +//#else +// if ( (far_nbrs->format == HALF_LIST +// && (j < system->n || atom_i->orig_id < atom_j->orig_id)) +// || far_nbrs->format == FULL_LIST ) +// { +// H->entries[Htop].j = j; +// +// 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; +// } +//#endif +// +// // hydrogen bond lists +// if ( control->hbond_cut > 0.0 +// && (ihb == 1 || ihb == 2) +// && far_nbrs->far_nbr_list.d[pj] <= control->hbond_cut ) +// { +// // fprintf( stderr, "%d %d\n", atom1, atom2 ); +// jhb = sbp_j->p_hbond; +// if ( ihb == 1 && jhb == 2 ) +// { +// hbonds->hbond_list[ihb_top].nbr = j; +// hbonds->hbond_list[ihb_top].scl = 1; +// hbonds->hbond_list[ihb_top].ptr = pj; +// ++ihb_top; +// ++num_hbonds; +// } +// // only add to list for local j (far nbrs is half-list) +// else if ( far_nbrs->format == HALF_LIST +// && (j < system->n && ihb == 2 && jhb == 1) ) +// { +// jhb_top = End_Index( atom_j->Hindex, hbonds ); +// hbonds->hbond_list[jhb_top].nbr = i; +// hbonds->hbond_list[jhb_top].scl = -1; +// hbonds->hbond_list[jhb_top].ptr = pj; +// Set_End_Index( atom_j->Hindex, jhb_top + 1, hbonds ); +// ++num_hbonds; +// } +// } +// } +//#if defined(NEUTRAL_TERRITORY) +// else if ( local == 2 ) +// { +// // H matrix entry +// if( ( atom_j->nt_dir != -1 && mark[atom_i->nt_dir] != mark[atom_j->nt_dir] +// && ( H->format == SYM_FULL_MATRIX +// || (H->format == SYM_HALF_MATRIX && atom_i->pos < atom_j->pos))) +// || ( j < system->n && atom_i->nt_dir != 0 && H->format == SYM_FULL_MATRIX )) +// { +// if( !nt_flag ) +// { +// nt_flag = 1; +// H->start[atom_i->pos] = Htop; +// } +// +// if( j < system->n ) +// { +// H->entries[Htop].j = j; +// } +// else +// { +// H->entries[Htop].j = atom_j->pos; +// } +// +// 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; +// } +// } +//#endif +// +// // uncorrected bond orders +// if ( //(workspace->bond_mark[i] < 3 || workspace->bond_mark[j] < 3) && +// far_nbrs->far_nbr_list.d[pj] <= control->bond_cut +// && BOp( workspace, bonds, control->bo_cut, +// i, btop_i, far_nbrs->far_nbr_list.nbr[pj], +// &far_nbrs->far_nbr_list.rel_box[pj], far_nbrs->far_nbr_list.d[pj], +// &far_nbrs->far_nbr_list.dvec[pj], far_nbrs->format, +// 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 == 1 ) +// { +// H->end[i] = Htop; +// if ( ihb == 1 ) +// Set_End_Index( atom_i->Hindex, ihb_top, hbonds ); +// } +//#if defined(NEUTRAL_TERRITORY) +// else if ( local == 2 ) +// { +// if( nt_flag ) +// { +// H->end[atom_i->pos] = Htop; +// } +// else +// { +// H->start[atom_i->pos] = 0; +// H->end[atom_i->pos] = 0; +// } +// } +//#endif +// } +// +// if ( far_nbrs->format == FULL_LIST ) +// { +// +// for( i = 0; i < system->N; ++i ) +// qsort( &bonds->bond_list[Start_Index(i, bonds)], +// Num_Entries(i, bonds), sizeof(bond_data), compare_bonds ); +// +// // set sym_index for bonds list (far_nbrs full list) +// for ( i = 0; i < system->N; ++i ) +// { +// start_i = Start_Index( i, bonds ); +// end_i = End_Index( i, bonds ); +// +// for ( btop_i = start_i; btop_i < end_i; ++btop_i ) +// { +// j = bonds->bond_list[btop_i].nbr; +// start_j = Start_Index( j, bonds ); +// end_j = End_Index( j, bonds ); +// +// for ( btop_j = start_j; btop_j < end_j; ++btop_j ) +// { +// if ( bonds->bond_list[btop_j].nbr == i ) +// { +// bonds->bond_list[btop_i].sym_index = btop_j; +// break; +// } +// } +// } +// } +// } +// +//#if defined(DEBUG) +// Print_Sparse_Matrix2( system, H, NULL ); +//#endif +// +// 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_noQEq( reax_system *system, control_params *control, @@ -1966,11 +1987,13 @@ void Init_Forces_noQEq( reax_system *system, control_params *control, 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 ); + /* put ghost atoms to an infinite distance (i.e., 1000) */ + workspace->bond_mark[i] = 1000; } num_bonds = 0; @@ -2317,21 +2340,33 @@ void Estimate_Storages( reax_system *system, control_params *control, 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; + else + { + C12 = 0.0; + BO_s = 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; + else + { + C34 = 0.0; + BO_pi = 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; + else + { + C56 = 0.0; + BO_pi2 = 0.0; + } /* Initially BO values are the uncorrected ones, page 1 */ BO = BO_s + BO_pi + BO_pi2; @@ -2354,7 +2389,7 @@ void Estimate_Storages( reax_system *system, control_params *control, * Therefore, we assume it is full and divide 2 if necessary. */ if ( cm_format == SYM_HALF_MATRIX ) { - *Htop = (*Htop + system->n) / 2; + *Htop = (*Htop + system->n + 1) / 2; } #endif @@ -2373,10 +2408,9 @@ void Estimate_Storages( reax_system *system, control_params *control, for ( i = 0; i < system->N; ++i ) { - *num_3body += SQR(bond_top[i]); - //if( i < system->n ) + *num_3body += SQR( bond_top[i] ); + //TODO: why x2? bond_top[i] = MAX( bond_top[i] * 2, MIN_BONDS ); - //else bond_top[i] = MAX_BONDS; } #if defined(DEBUG_FOCUS) @@ -2397,12 +2431,12 @@ void Compute_Forces( reax_system *system, control_params *control, #if defined(LOG_PERFORMANCE) real t_start = 0.0, t_end; - //MPI_Barrier( mpi_data->world ); if ( system->my_rank == MASTER_NODE ) { t_start = MPI_Wtime(); } #endif + comm = mpi_data->world; /********* init forces ************/ @@ -2467,7 +2501,6 @@ void Compute_Forces( reax_system *system, control_params *control, } #if defined(LOG_PERFORMANCE) - //MPI_Barrier( mpi_data->world ); if ( system->my_rank == MASTER_NODE ) { t_end = MPI_Wtime( ); @@ -2487,7 +2520,6 @@ void Compute_Forces( reax_system *system, control_params *control, lists, out_control, mpi_data->world ); #if defined(LOG_PERFORMANCE) - //MPI_Barrier( mpi_data->world ); if ( system->my_rank == MASTER_NODE ) { t_end = MPI_Wtime( ); @@ -2506,7 +2538,6 @@ void Compute_Forces( reax_system *system, control_params *control, Compute_Total_Force( system, control, data, workspace, lists, mpi_data ); #if defined(LOG_PERFORMANCE) - //MPI_Barrier( mpi_data->world ); if ( system->my_rank == MASTER_NODE ) { t_end = MPI_Wtime( ); @@ -2517,12 +2548,13 @@ void Compute_Forces( reax_system *system, control_params *control, #if defined(DEBUG_FOCUS) fprintf( stderr, "p%d @ step%d: total forces computed\n", system->my_rank, data->step ); + //Print_Total_Force( system, data, workspace ); MPI_Barrier( mpi_data->world ); #endif #if defined(TEST_FORCES) Print_Force_Files( system, control, data, workspace, - lists, out_control, mpi_data ); + lists, out_control, mpi_data ); #endif } diff --git a/PuReMD/src/reax_types.h b/PuReMD/src/reax_types.h index 8a94c0c9..d93ec5c2 100644 --- a/PuReMD/src/reax_types.h +++ b/PuReMD/src/reax_types.h @@ -1033,9 +1033,9 @@ typedef struct real *dDelta_lp, *dDelta_lp_temp; real *nlp, *nlp_temp, *Clp, *vlpex; rvec *dDeltap_self; - int *bond_mark, *done_after; + int *bond_mark; - /* QEq storage */ + /* charge matrix storage */ sparse_matrix *H; sparse_matrix *L; sparse_matrix *U; @@ -1051,23 +1051,23 @@ typedef struct real *y, *g; real *hc, *hs; real **h, **v; - /* GMRES, PIPECG storage */ + /* GMRES, PIPECG, PIPECR storage */ real *z; - /* CG, PIPECG storage */ + /* CG, PIPECG, PIPECR storage */ real *d, *p, *q, *r; - /* PIPECG storage */ + /* PIPECG, PIPECR storage */ real *m, *n, *u, *w; /* dual-CG storage */ rvec2 *r2, *d2, *q2, *p2; /* Taper */ - real Tap[8]; //Tap7, Tap6, Tap5, Tap4, Tap3, Tap2, Tap1, Tap0; + real Tap[8]; /* storage for analysis */ - int *mark, *old_mark; + int *mark, *old_mark; rvec *x_old; /* storage space for bond restrictions */ - int *restricted; + int *restricted; int **restricted_list; /* integrator */ -- GitLab