diff --git a/sPuReMD/src/allocate.c b/sPuReMD/src/allocate.c index 22bfedc9cf8b1e157ffe35335c9ea210a097b405..89eefe4eb13db3484de4ae717bf13103e84d82de 100644 --- a/sPuReMD/src/allocate.c +++ b/sPuReMD/src/allocate.c @@ -27,38 +27,64 @@ /* allocate space for atoms */ void PreAllocate_Space( reax_system *system, control_params *control, - static_storage *workspace ) + static_storage *workspace, int n, int first_run ) { int i; - system->atoms = scalloc( system->N, sizeof(reax_atom), - "PreAllocate_Space::system->atoms" ); - workspace->orig_id = scalloc( system->N, sizeof(int), - "PreAllocate_Space::workspace->orid_id" ); - - /* bond restriction info */ - if ( control->restrict_bonds ) + if ( first_run == TRUE ) { - workspace->restricted = scalloc( system->N, sizeof(int), - "PreAllocate_Space::workspace->restricted_atoms" ); + system->atoms = scalloc( n, sizeof(reax_atom), + "PreAllocate_Space::system->atoms" ); + workspace->orig_id = scalloc( n, sizeof(int), + "PreAllocate_Space::workspace->orid_id" ); + + /* bond restriction info */ + if ( control->restrict_bonds ) + { + workspace->restricted = scalloc( n, sizeof(int), + "PreAllocate_Space::workspace->restricted_atoms" ); + + workspace->restricted_list = scalloc( n, sizeof(int*), + "PreAllocate_Space::workspace->restricted_list" ); - workspace->restricted_list = scalloc( system->N, sizeof(int*), - "PreAllocate_Space::workspace->restricted_list" ); + for ( i = 0; i < n; ++i ) + { + workspace->restricted_list[i] = scalloc( MAX_RESTRICT, sizeof(int), + "PreAllocate_Space::workspace->restricted_list[i]" ); + } + } + } + else + { + system->atoms = srealloc( system->atoms, n * sizeof(reax_atom), + "PreAllocate_Space::system->atoms" ); + workspace->orig_id = srealloc( workspace->orig_id, n * sizeof(int), + "PreAllocate_Space::workspace->orid_id" ); - for ( i = 0; i < system->N; ++i ) + /* bond restriction info */ + if ( control->restrict_bonds ) { - workspace->restricted_list[i] = scalloc( MAX_RESTRICT, sizeof(int), - "PreAllocate_Space::workspace->restricted_list[i]" ); + workspace->restricted = srealloc( workspace->restricted, n * sizeof(int), + "PreAllocate_Space::workspace->restricted_atoms" ); + + workspace->restricted_list = srealloc( workspace->restricted_list, n * sizeof(int*), + "PreAllocate_Space::workspace->restricted_list" ); + + for ( i = 0; i < n; ++i ) + { + workspace->restricted_list[i] = srealloc( workspace->restricted_list[i], MAX_RESTRICT * sizeof(int), + "PreAllocate_Space::workspace->restricted_list[i]" ); + } } } } -static void Reallocate_Neighbor_List( reax_list *far_nbrs, int n, int num_intrs ) +static void Reallocate_Neighbor_List( reax_list *far_nbrs, int n, int n_max, int num_intrs ) { Delete_List( TYP_FAR_NEIGHBOR, far_nbrs ); - Make_List( n, num_intrs, TYP_FAR_NEIGHBOR, far_nbrs ); + Make_List( n, n_max, num_intrs, TYP_FAR_NEIGHBOR, far_nbrs ); #if defined(DEBUG_FOCUS) fprintf( stderr, "num_far = %d, far_nbrs = %d -> reallocating!\n", @@ -72,10 +98,11 @@ static void Reallocate_Neighbor_List( reax_list *far_nbrs, int n, int num_intrs /* Dynamic allocation of memory for matrix in CSR format * * pH (output): pointer to sparse matrix for which to allocate - * n: dimension of the matrix + * n: num. rows of the matrix + * n_max: max. num. rows of the matrix * m: number of nonzeros to allocate space for in matrix * */ -void Allocate_Matrix( sparse_matrix **pH, int n, int m ) +void Allocate_Matrix( sparse_matrix **pH, int n, int n_max, int m ) { sparse_matrix *H; @@ -83,9 +110,10 @@ void Allocate_Matrix( sparse_matrix **pH, int n, int m ) H = *pH; H->n = n; + H->n_max = n_max; H->m = m; - H->start = smalloc( sizeof(unsigned int) * (n + 1), "Allocate_Matrix::H->start" ); + H->start = smalloc( sizeof(unsigned int) * (n_max + 1), "Allocate_Matrix::H->start" ); H->j = smalloc( sizeof(unsigned int) * m, "Allocate_Matrix::H->j" ); H->val = smalloc( sizeof(real) * m, "Allocate_Matrix::H->val" ); } @@ -104,15 +132,15 @@ void Deallocate_Matrix( sparse_matrix *H ) } -static void Reallocate_Matrix( sparse_matrix **H, int n, int m ) +static void Reallocate_Matrix( sparse_matrix **H, int n, int n_max, int m ) { Deallocate_Matrix( *H ); - Allocate_Matrix( H, n, m ); + Allocate_Matrix( H, n, n_max, m ); } -void Allocate_HBond_List( int n, int num_h, int *h_index, int *hb_top, +void Allocate_HBond_List( int n, int num_h, int num_h_max, int *h_index, int *hb_top, reax_list *hbonds ) { int i, num_hbonds; @@ -125,7 +153,7 @@ void Allocate_HBond_List( int n, int num_h, int *h_index, int *hb_top, } num_hbonds = hb_top[n - 1]; - Make_List( num_h, num_hbonds, TYP_HBOND, hbonds ); + Make_List( num_h, num_h_max, num_hbonds, TYP_HBOND, hbonds ); for ( i = 0; i < n; ++i ) { @@ -149,7 +177,8 @@ void Allocate_HBond_List( int n, int num_h, int *h_index, int *hb_top, } -static void Reallocate_HBonds_List( int n, int num_h, int *h_index, reax_list *hbonds ) +static void Reallocate_HBonds_List( int n, int num_h, int num_h_max, + int *h_index, reax_list *hbonds ) { int i; int *hb_top; @@ -165,13 +194,13 @@ static void Reallocate_HBonds_List( int n, int num_h, int *h_index, reax_list *h Delete_List( TYP_HBOND, hbonds ); - Allocate_HBond_List( n, num_h, h_index, hb_top, hbonds ); + Allocate_HBond_List( n, num_h, num_h_max, h_index, hb_top, hbonds ); sfree( hb_top, "Reallocate_HBonds_List::hb_top" ); } -void Allocate_Bond_List( int n, int *bond_top, reax_list *bonds ) +void Allocate_Bond_List( int n, int n_max, int *bond_top, reax_list *bonds ) { int i, num_bonds; @@ -183,7 +212,7 @@ void Allocate_Bond_List( int n, int *bond_top, reax_list *bonds ) } num_bonds = bond_top[n - 1]; - Make_List( n, num_bonds, TYP_BOND, bonds ); + Make_List( n, n_max, num_bonds, TYP_BOND, bonds ); Set_Start_Index( 0, 0, bonds ); Set_End_Index( 0, 0, bonds ); @@ -201,7 +230,8 @@ void Allocate_Bond_List( int n, int *bond_top, reax_list *bonds ) } -static void Reallocate_Bonds_List( int n, reax_list *bonds, int *num_bonds, int *est_3body ) +static void Reallocate_Bonds_List( int n, int n_max, reax_list *bonds, + int *num_bonds, int *est_3body ) { int i; int *bond_top; @@ -221,7 +251,7 @@ static void Reallocate_Bonds_List( int n, reax_list *bonds, int *num_bonds, int Delete_List( TYP_BOND, bonds ); - Allocate_Bond_List( n, bond_top, bonds ); + Allocate_Bond_List( n, n_max, bond_top, bonds ); *num_bonds = bond_top[n - 1]; sfree( bond_top, "Reallocate_Bonds_List::bond_top" ); @@ -242,13 +272,13 @@ void Reallocate( reax_system *system, control_params *control, static_storage *w if ( realloc->num_far > 0 && nbr_flag == TRUE ) { Reallocate_Neighbor_List( lists[FAR_NBRS], - system->N, realloc->num_far * SAFE_ZONE ); + system->N, system->N_max, realloc->num_far * SAFE_ZONE ); realloc->num_far = -1; } if ( realloc->Htop > 0 ) { - Reallocate_Matrix( &workspace->H, system->N_cm, + Reallocate_Matrix( &workspace->H, system->N_cm, system->N_cm_max, realloc->Htop * SAFE_ZONE ); realloc->Htop = -1; @@ -260,15 +290,15 @@ void Reallocate( reax_system *system, control_params *control, static_storage *w if ( control->hbond_cut > 0.0 && realloc->hbonds > 0 ) { - Reallocate_HBonds_List( system->N, workspace->num_H, workspace->hbond_index, - lists[HBONDS] ); + Reallocate_HBonds_List( system->N, workspace->num_H, workspace->num_H_max, + workspace->hbond_index, lists[HBONDS] ); realloc->hbonds = -1; } num_bonds = est_3body = -1; if ( realloc->bonds > 0 ) { - Reallocate_Bonds_List( system->N, lists[BONDS], &num_bonds, &est_3body ); + Reallocate_Bonds_List( system->N, system->N_max, lists[BONDS], &num_bonds, &est_3body ); realloc->bonds = -1; realloc->num_3body = MAX( realloc->num_3body, est_3body ); } @@ -283,14 +313,15 @@ void Reallocate( reax_system *system, control_params *control, static_storage *w } realloc->num_3body *= SAFE_ZONE; - Make_List( num_bonds, realloc->num_3body, + Make_List( num_bonds, num_bonds, realloc->num_3body, TYP_THREE_BODY, lists[THREE_BODIES] ); realloc->num_3body = -1; + #if defined(DEBUG_FOCUS) - fprintf( stderr, "reallocating 3 bodies\n" ); - fprintf( stderr, "reallocated - num_bonds: %d\n", num_bonds ); - fprintf( stderr, "reallocated - num_3body: %d\n", realloc->num_3body ); - fprintf( stderr, "reallocated 3body memory: %ldMB\n", + fprintf( stderr, "[INFO] reallocating 3 bodies\n" ); + fprintf( stderr, "[INFO] reallocated - num_bonds: %d\n", num_bonds ); + fprintf( stderr, "[INFO] reallocated - num_3body: %d\n", realloc->num_3body ); + fprintf( stderr, "[INFO] reallocated 3body memory: %ldMB\n", realloc->num_3body * sizeof(three_body_interaction_data) / (1024 * 1024) ); #endif @@ -299,16 +330,15 @@ void Reallocate( reax_system *system, control_params *control, static_storage *w if ( realloc->gcell_atoms > -1 ) { #if defined(DEBUG_FOCUS) - fprintf(stderr, "reallocating gcell: g->max_atoms: %d\n", g->max_atoms); + fprintf( stderr, "[INFO] reallocating gcell: g->max_atoms: %d\n", g->max_atoms ); #endif - for ( i = 0; i < g->ncell[0]; i++ ) + for ( i = 0; i < g->ncell_max[0]; i++ ) { - for ( j = 0; j < g->ncell[1]; j++ ) + for ( j = 0; j < g->ncell_max[1]; j++ ) { - for ( k = 0; k < g->ncell[2]; k++ ) + for ( k = 0; k < g->ncell_max[2]; k++ ) { - // reallocate g->atoms sfree( g->atoms[i][j][k], "Reallocate::g->atoms[i][j][k]" ); g->atoms[i][j][k] = scalloc( workspace->realloc.gcell_atoms, sizeof(int), "Reallocate::g->atoms[i][j][k]" ); diff --git a/sPuReMD/src/allocate.h b/sPuReMD/src/allocate.h index ae5270d849b78b516a634d705b741f9b93c42d97..e4cd681904a6328ac8bd553c4eb689ad63ad9a4e 100644 --- a/sPuReMD/src/allocate.h +++ b/sPuReMD/src/allocate.h @@ -25,17 +25,17 @@ #include "reax_types.h" -void PreAllocate_Space( reax_system*, control_params*, static_storage* ); +void PreAllocate_Space( reax_system*, control_params*, static_storage*, int, int ); void Reallocate( reax_system*, control_params*, static_storage*, reax_list**, int ); -void Allocate_Matrix( sparse_matrix**, int, int ); +void Allocate_Matrix( sparse_matrix**, int, int, int ); void Deallocate_Matrix( sparse_matrix* ); -void Allocate_HBond_List( int, int, int*, int*, reax_list* ); +void Allocate_HBond_List( int, int, int, int*, int*, reax_list* ); -void Allocate_Bond_List( int, int*, reax_list* ); +void Allocate_Bond_List( int, int, int*, reax_list* ); #endif diff --git a/sPuReMD/src/charges.c b/sPuReMD/src/charges.c index 193de2194aedcefdfb5c2723a60509d4dcb81236..57bc2e0cde0ab6e1d823fbbed4ce0fbf34226b07 100644 --- a/sPuReMD/src/charges.c +++ b/sPuReMD/src/charges.c @@ -1186,16 +1186,16 @@ static void Setup_Preconditioner_QEq( const reax_system * const system, if ( workspace->L == NULL ) { - Allocate_Matrix( &workspace->L, Hptr->n, fillin ); - Allocate_Matrix( &workspace->U, Hptr->n, fillin ); + Allocate_Matrix( &workspace->L, Hptr->n, Hptr->n_max, fillin ); + Allocate_Matrix( &workspace->U, Hptr->n, Hptr->n_max, fillin ); } else if ( workspace->L->m < fillin ) { Deallocate_Matrix( workspace->L ); Deallocate_Matrix( workspace->U ); - Allocate_Matrix( &workspace->L, Hptr->n, fillin ); - Allocate_Matrix( &workspace->U, Hptr->n, fillin ); + Allocate_Matrix( &workspace->L, Hptr->n, Hptr->n_max, fillin ); + Allocate_Matrix( &workspace->U, Hptr->n, Hptr->n_max, fillin ); } break; @@ -1207,16 +1207,16 @@ static void Setup_Preconditioner_QEq( const reax_system * const system, if ( workspace->L == NULL ) { - Allocate_Matrix( &workspace->L, Hptr->n, Hptr->m ); - Allocate_Matrix( &workspace->U, Hptr->n, Hptr->m ); + Allocate_Matrix( &workspace->L, Hptr->n, Hptr->n_max, Hptr->m ); + Allocate_Matrix( &workspace->U, Hptr->n, Hptr->n_max, Hptr->m ); } else if ( workspace->L->m < Hptr->m ) { Deallocate_Matrix( workspace->L ); Deallocate_Matrix( workspace->U ); - Allocate_Matrix( &workspace->L, Hptr->n, Hptr->m ); - Allocate_Matrix( &workspace->U, Hptr->n, Hptr->m ); + Allocate_Matrix( &workspace->L, Hptr->n, Hptr->n_max, Hptr->m ); + Allocate_Matrix( &workspace->U, Hptr->n, Hptr->n_max, Hptr->m ); } break; @@ -1228,8 +1228,8 @@ static void Setup_Preconditioner_QEq( const reax_system * const system, { /* safest storage estimate is ILU(0) (same as * lower triangular portion of H), could improve later */ - Allocate_Matrix( &workspace->L, Hptr->n, Hptr->m ); - Allocate_Matrix( &workspace->U, Hptr->n, Hptr->m ); + Allocate_Matrix( &workspace->L, Hptr->n, Hptr->n_max, Hptr->m ); + Allocate_Matrix( &workspace->U, Hptr->n, Hptr->n_max, Hptr->m ); } else if ( workspace->L->m < Hptr->m ) { @@ -1238,8 +1238,8 @@ static void Setup_Preconditioner_QEq( const reax_system * const system, /* safest storage estimate is ILU(0) (same as * lower triangular portion of H), could improve later */ - Allocate_Matrix( &workspace->L, Hptr->n, Hptr->m ); - Allocate_Matrix( &workspace->U, Hptr->n, Hptr->m ); + Allocate_Matrix( &workspace->L, Hptr->n, Hptr->n_max, Hptr->m ); + Allocate_Matrix( &workspace->U, Hptr->n, Hptr->n_max, Hptr->m ); } break; @@ -1317,16 +1317,16 @@ static void Setup_Preconditioner_EE( const reax_system * const system, if ( workspace->L == NULL ) { - Allocate_Matrix( &workspace->L, Hptr->n, Hptr->m ); - Allocate_Matrix( &workspace->U, Hptr->n, Hptr->m ); + Allocate_Matrix( &workspace->L, Hptr->n, Hptr->n_max, Hptr->m ); + Allocate_Matrix( &workspace->U, Hptr->n, Hptr->n_max, Hptr->m ); } else if ( workspace->L->m < Hptr->m ) { Deallocate_Matrix( workspace->L ); Deallocate_Matrix( workspace->U ); - Allocate_Matrix( &workspace->L, Hptr->n, Hptr->m ); - Allocate_Matrix( &workspace->U, Hptr->n, Hptr->m ); + Allocate_Matrix( &workspace->L, Hptr->n, Hptr->n_max, Hptr->m ); + Allocate_Matrix( &workspace->U, Hptr->n, Hptr->n_max, Hptr->m ); } break; @@ -1344,8 +1344,8 @@ static void Setup_Preconditioner_EE( const reax_system * const system, { /* safest storage estimate is ILU(0) (same as * lower triangular portion of H), could improve later */ - Allocate_Matrix( &workspace->L, Hptr->n, Hptr->m ); - Allocate_Matrix( &workspace->U, Hptr->n, Hptr->m ); + Allocate_Matrix( &workspace->L, Hptr->n, Hptr->n_max, Hptr->m ); + Allocate_Matrix( &workspace->U, Hptr->n, Hptr->n_max, Hptr->m ); } else if ( workspace->L->m < Hptr->m ) { @@ -1354,8 +1354,8 @@ static void Setup_Preconditioner_EE( const reax_system * const system, /* safest storage estimate is ILU(0) (same as * lower triangular portion of H), could improve later */ - Allocate_Matrix( &workspace->L, Hptr->n, Hptr->m ); - Allocate_Matrix( &workspace->U, Hptr->n, Hptr->m ); + Allocate_Matrix( &workspace->L, Hptr->n, Hptr->n_max, Hptr->m ); + Allocate_Matrix( &workspace->U, Hptr->n, Hptr->n_max, Hptr->m ); } break; @@ -1435,16 +1435,16 @@ static void Setup_Preconditioner_ACKS2( const reax_system * const system, if ( workspace->L == NULL ) { - Allocate_Matrix( &workspace->L, Hptr->n, Hptr->m ); - Allocate_Matrix( &workspace->U, Hptr->n, Hptr->m ); + Allocate_Matrix( &workspace->L, Hptr->n, Hptr->n_max, Hptr->m ); + Allocate_Matrix( &workspace->U, Hptr->n, Hptr->n_max, Hptr->m ); } else if ( workspace->L->m < Hptr->m ) { Deallocate_Matrix( workspace->L ); Deallocate_Matrix( workspace->U ); - Allocate_Matrix( &workspace->L, Hptr->n, Hptr->m ); - Allocate_Matrix( &workspace->U, Hptr->n, Hptr->m ); + Allocate_Matrix( &workspace->L, Hptr->n, Hptr->n_max, Hptr->m ); + Allocate_Matrix( &workspace->U, Hptr->n, Hptr->n_max, Hptr->m ); } break; @@ -1464,8 +1464,8 @@ static void Setup_Preconditioner_ACKS2( const reax_system * const system, { /* safest storage estimate is ILU(0) (same as * lower triangular portion of H), could improve later */ - Allocate_Matrix( &workspace->L, Hptr->n, Hptr->m ); - Allocate_Matrix( &workspace->U, Hptr->n, Hptr->m ); + Allocate_Matrix( &workspace->L, Hptr->n, Hptr->n_max, Hptr->m ); + Allocate_Matrix( &workspace->U, Hptr->n, Hptr->n_max, Hptr->m ); } else if ( workspace->L->m < Hptr->m ) { @@ -1473,8 +1473,8 @@ static void Setup_Preconditioner_ACKS2( const reax_system * const system, Deallocate_Matrix( workspace->U ); /* factors have sparsity pattern as H */ - Allocate_Matrix( &workspace->L, Hptr->n, Hptr->m ); - Allocate_Matrix( &workspace->U, Hptr->n, Hptr->m ); + Allocate_Matrix( &workspace->L, Hptr->n, Hptr->n_max, Hptr->m ); + Allocate_Matrix( &workspace->U, Hptr->n, Hptr->n_max, Hptr->m ); } break; diff --git a/sPuReMD/src/ffield.c b/sPuReMD/src/ffield.c index 1549998a74faebd8e808910096cc2ae1df80b60a..f536dc36c369e4acf8750a66b0b5866b97e015fd 100644 --- a/sPuReMD/src/ffield.c +++ b/sPuReMD/src/ffield.c @@ -26,7 +26,7 @@ #include "tool_box.h" -void Read_Force_Field( FILE* fp, reax_interaction* reax ) +void Read_Force_Field( FILE *fp, reax_interaction *reax, int first_run ) { char *s; char **tmp; @@ -54,15 +54,23 @@ void Read_Force_Field( FILE* fp, reax_interaction* reax ) /* reading the number of global parameters */ n = atoi(tmp[0]); - if (n < 1) + if ( n < 1 ) { fprintf( stderr, "[WARNING] number of globals in ffield file is 0!\n" ); return; } + if ( first_run == TRUE ) + { + reax->gp.l = (real*) smalloc( sizeof(real) * n, + "Read_Force_Field::reax->gp-l" ); + } + else if ( reax->gp.n_global < n ) + { + reax->gp.l = (real*) srealloc( reax->gp.l, sizeof(real) * n, + "Read_Force_Field::reax->gp-l" ); + } reax->gp.n_global = n; - reax->gp.l = (real*) smalloc( sizeof(real) * n, - "Read_Force_Field::reax->gp-l" ); /* see reax_types.h for mapping between l[i] and the lambdas used in ff */ for ( i = 0; i < n; i++ ) @@ -78,61 +86,121 @@ void Read_Force_Field( FILE* fp, reax_interaction* reax ) /* next line is number of atom types and some comments */ fgets( s, MAX_LINE, fp ); Tokenize( s, &tmp, MAX_TOKEN_LEN ); - reax->num_atom_types = atoi(tmp[0]); + n = atoi(tmp[0]); /* 3 lines of comments */ - fgets(s, MAX_LINE, fp); - fgets(s, MAX_LINE, fp); - fgets(s, MAX_LINE, fp); + fgets( s, MAX_LINE, fp ); + fgets( s, MAX_LINE, fp ); + fgets( s, MAX_LINE, fp ); - /* Allocating structures in reax_interaction */ - reax->sbp = (single_body_parameters*) scalloc( reax->num_atom_types, sizeof(single_body_parameters), - "Read_Force_Field::reax->sbp" ); - reax->tbp = (two_body_parameters**) scalloc( reax->num_atom_types, sizeof(two_body_parameters*), - "Read_Force_Field::reax->tbp" ); - reax->thbp = (three_body_header***) scalloc( reax->num_atom_types, sizeof(three_body_header**), - "Read_Force_Field::reax->thbp" ); - reax->hbp = (hbond_parameters***) scalloc( reax->num_atom_types, sizeof(hbond_parameters**), - "Read_Force_Field::reax->hbp" ); - reax->fbp = (four_body_header****) scalloc( reax->num_atom_types, sizeof(four_body_header***), - "Read_Force_Field::reax->fbp" ); - tor_flag = (char****) scalloc( reax->num_atom_types, sizeof(char***), + if ( first_run == TRUE ) + { + /* Allocating structures in reax_interaction */ + reax->sbp = (single_body_parameters*) scalloc( n, sizeof(single_body_parameters), + "Read_Force_Field::reax->sbp" ); + reax->tbp = (two_body_parameters**) scalloc( n, sizeof(two_body_parameters*), + "Read_Force_Field::reax->tbp" ); + reax->thbp = (three_body_header***) scalloc( n, sizeof(three_body_header**), + "Read_Force_Field::reax->thbp" ); + reax->hbp = (hbond_parameters***) scalloc( n, sizeof(hbond_parameters**), + "Read_Force_Field::reax->hbp" ); + reax->fbp = (four_body_header****) scalloc( n, sizeof(four_body_header***), + "Read_Force_Field::reax->fbp" ); + + for ( i = 0; i < n; i++ ) + { + reax->tbp[i] = (two_body_parameters*) scalloc( n, sizeof(two_body_parameters), + "Read_Force_Field::reax->tbp[i]" ); + reax->thbp[i] = (three_body_header**) scalloc( n, sizeof(three_body_header*), + "Read_Force_Field::reax->thbp[i]" ); + reax->hbp[i] = (hbond_parameters**) scalloc( n, sizeof(hbond_parameters*), + "Read_Force_Field::reax->hbp[i]" ); + reax->fbp[i] = (four_body_header***) scalloc( n, sizeof(four_body_header**), + "Read_Force_Field::reax->fbp[i]" ); + + for ( j = 0; j < n; j++ ) + { + reax->thbp[i][j] = (three_body_header*) scalloc( n, sizeof(three_body_header), + "Read_Force_Field::reax->thbp[i][j]" ); + reax->hbp[i][j] = (hbond_parameters*) scalloc( n, sizeof(hbond_parameters), + "Read_Force_Field::reax->hbp[i][j]" ); + reax->fbp[i][j] = (four_body_header**) scalloc( n, sizeof(four_body_header*), + "Read_Force_Field::reax->fbp[i][j]" ); + + for ( k = 0; k < n; k++ ) + { + reax->fbp[i][j][k] = (four_body_header*) scalloc( n, sizeof(four_body_header), + "Read_Force_Field::reax->fbp[i][j][k]" ); + } + } + } + } + else if ( reax->num_atom_types < n ) + { + /* Allocating structures in reax_interaction */ + reax->sbp = (single_body_parameters*) srealloc( reax->sbp, n * sizeof(single_body_parameters), + "Read_Force_Field::reax->sbp" ); + reax->tbp = (two_body_parameters**) srealloc( reax->tbp, n * sizeof(two_body_parameters*), + "Read_Force_Field::reax->tbp" ); + reax->thbp = (three_body_header***) srealloc( reax->thbp, n * sizeof(three_body_header**), + "Read_Force_Field::reax->thbp" ); + reax->hbp = (hbond_parameters***) srealloc( reax->hbp, n * sizeof(hbond_parameters**), + "Read_Force_Field::reax->hbp" ); + reax->fbp = (four_body_header****) srealloc( reax->fbp, n * sizeof(four_body_header***), + "Read_Force_Field::reax->fbp" ); + + for ( i = 0; i < n; i++ ) + { + reax->tbp[i] = (two_body_parameters*) srealloc( reax->tbp[i], n * sizeof(two_body_parameters), + "Read_Force_Field::reax->tbp[i]" ); + reax->thbp[i] = (three_body_header**) srealloc( reax->thbp[i], n * sizeof(three_body_header*), + "Read_Force_Field::reax->thbp[i]" ); + reax->hbp[i] = (hbond_parameters**) srealloc( reax->hbp[i], n * sizeof(hbond_parameters*), + "Read_Force_Field::reax->hbp[i]" ); + reax->fbp[i] = (four_body_header***) srealloc( reax->fbp[i], n * sizeof(four_body_header**), + "Read_Force_Field::reax->fbp[i]" ); + + for ( j = 0; j < n; j++ ) + { + reax->thbp[i][j] = (three_body_header*) srealloc( reax->thbp[i][j], n * sizeof(three_body_header), + "Read_Force_Field::reax->thbp[i][j]" ); + reax->hbp[i][j] = (hbond_parameters*) srealloc( reax->hbp[i][j], n * sizeof(hbond_parameters), + "Read_Force_Field::reax->hbp[i][j]" ); + reax->fbp[i][j] = (four_body_header**) srealloc( reax->fbp[i][j], n * sizeof(four_body_header*), + "Read_Force_Field::reax->fbp[i][j]" ); + + for ( k = 0; k < n; k++ ) + { + reax->fbp[i][j][k] = (four_body_header*) srealloc( reax->fbp[i][j][k], n * sizeof(four_body_header), + "Read_Force_Field::reax->fbp[i][j][k]" ); + } + } + } + } + + tor_flag = (char****) smalloc( n * sizeof(char***), "Read_Force_Field::tor_flag" ); - for ( i = 0; i < reax->num_atom_types; i++ ) + for ( i = 0; i < n; i++ ) { - reax->tbp[i] = (two_body_parameters*) scalloc( reax->num_atom_types, sizeof(two_body_parameters), - "Read_Force_Field::reax->tbp[i]" ); - reax->thbp[i] = (three_body_header**) scalloc( reax->num_atom_types, sizeof(three_body_header*), - "Read_Force_Field::reax->thbp[i]" ); - reax->hbp[i] = (hbond_parameters**) scalloc( reax->num_atom_types, sizeof(hbond_parameters*), - "Read_Force_Field::reax->hbp[i]" ); - reax->fbp[i] = (four_body_header***) scalloc( reax->num_atom_types, sizeof(four_body_header**), - "Read_Force_Field::reax->fbp[i]" ); - tor_flag[i] = (char***) scalloc( reax->num_atom_types, sizeof(char**), + tor_flag[i] = (char***) smalloc( n * sizeof(char**), "Read_Force_Field::tor_flag[i]" ); - for ( j = 0; j < reax->num_atom_types; j++ ) + for ( j = 0; j < n; j++ ) { - reax->thbp[i][j] = (three_body_header*) scalloc( reax->num_atom_types, sizeof(three_body_header), - "Read_Force_Field::reax->thbp[i][j]" ); - reax->hbp[i][j] = (hbond_parameters*) scalloc( reax->num_atom_types, sizeof(hbond_parameters), - "Read_Force_Field::reax->hbp[i][j]" ); - reax->fbp[i][j] = (four_body_header**) scalloc( reax->num_atom_types, sizeof(four_body_header*), - "Read_Force_Field::reax->fbp[i][j]" ); - tor_flag[i][j] = (char**) scalloc( reax->num_atom_types, sizeof(char*), + tor_flag[i][j] = (char**) smalloc( n * sizeof(char*), "Read_Force_Field::tor_flag[i][j]" ); - for (k = 0; k < reax->num_atom_types; k++) + for ( k = 0; k < n; k++ ) { - reax->fbp[i][j][k] = (four_body_header*) scalloc( reax->num_atom_types, sizeof(four_body_header), - "Read_Force_Field::reax->fbp[i][j][k]" ); - tor_flag[i][j][k] = (char*) scalloc( reax->num_atom_types, sizeof(char), + tor_flag[i][j][k] = (char*) smalloc( n * sizeof(char), "Read_Force_Field::tor_flag[i][j][k]" ); } } } + reax->num_atom_types = n; + // vdWaals type: 1: Shielded Morse, no inner-wall // 2: inner wall, no shielding // 3: inner wall+shielding @@ -340,7 +408,7 @@ void Read_Force_Field( FILE* fp, reax_interaction* reax ) /* a line of comments */ fgets(s, MAX_LINE, fp); - for (i = 0; i < l; i++) + for ( i = 0; i < l; i++ ) { /* line 1 */ fgets( s, MAX_LINE, fp ); @@ -349,7 +417,7 @@ void Read_Force_Field( FILE* fp, reax_interaction* reax ) j = atoi(tmp[0]) - 1; k = atoi(tmp[1]) - 1; - if (j < reax->num_atom_types && k < reax->num_atom_types) + if ( j < reax->num_atom_types && k < reax->num_atom_types ) { val = atof(tmp[2]); @@ -481,35 +549,35 @@ void Read_Force_Field( FILE* fp, reax_interaction* reax ) } val = atof(tmp[3]); - if (val > 0.0) + if ( val > 0.0 ) { reax->tbp[j][k].r_vdW = 2.0 * val; reax->tbp[k][j].r_vdW = 2.0 * val; } val = atof(tmp[4]); - if (val > 0.0) + if ( val > 0.0 ) { reax->tbp[j][k].alpha = val; reax->tbp[k][j].alpha = val; } val = atof(tmp[5]); - if (val > 0.0) + if ( val > 0.0 ) { reax->tbp[j][k].r_s = val; reax->tbp[k][j].r_s = val; } val = atof(tmp[6]); - if (val > 0.0) + if ( val > 0.0 ) { reax->tbp[j][k].r_p = val; reax->tbp[k][j].r_p = val; } val = atof(tmp[7]); - if (val > 0.0) + if ( val > 0.0 ) { reax->tbp[j][k].r_pp = val; reax->tbp[k][j].r_pp = val; @@ -545,9 +613,9 @@ void Read_Force_Field( FILE* fp, reax_interaction* reax ) k = atoi(tmp[1]) - 1; m = atoi(tmp[2]) - 1; - if (j < reax->num_atom_types && - k < reax->num_atom_types && - m < reax->num_atom_types) + if ( j < reax->num_atom_types + && k < reax->num_atom_types + && m < reax->num_atom_types ) { cnt = reax->thbp[j][k][m].cnt; reax->thbp[j][k][m].cnt++; @@ -623,12 +691,12 @@ void Read_Force_Field( FILE* fp, reax_interaction* reax ) n = atoi(tmp[3]) - 1; /* this means the entry is not in compact form */ - if (j >= 0 && n >= 0) + if ( j >= 0 && n >= 0 ) { - if (j < reax->num_atom_types && - k < reax->num_atom_types && - m < reax->num_atom_types && - n < reax->num_atom_types) + if ( j < reax->num_atom_types + && k < reax->num_atom_types + && m < reax->num_atom_types + && n < reax->num_atom_types ) { /* these flags ensure that this entry take precedence * over the compact form entries */ @@ -679,7 +747,7 @@ void Read_Force_Field( FILE* fp, reax_interaction* reax ) // reax->fbp[p][k][m][o].cnt++; // reax->fbp[o][m][k][p].cnt++; - if (tor_flag[p][k][m][o] == 0) + if ( tor_flag[p][k][m][o] == 0 ) { reax->fbp[p][k][m][o].prm[0].V1 = atof(tmp[4]); reax->fbp[p][k][m][o].prm[0].V2 = atof(tmp[5]); @@ -688,7 +756,7 @@ void Read_Force_Field( FILE* fp, reax_interaction* reax ) reax->fbp[p][k][m][o].prm[0].p_cot1 = atof(tmp[8]); } - if (tor_flag[o][m][k][p] == 0) + if ( tor_flag[o][m][k][p] == 0 ) { reax->fbp[o][m][k][p].prm[0].V1 = atof(tmp[4]); reax->fbp[o][m][k][p].prm[0].V2 = atof(tmp[5]); diff --git a/sPuReMD/src/ffield.h b/sPuReMD/src/ffield.h index 611a705d7afc3bf823995b75efcf9f0e2778e23b..47b0eb6b4d9fcec9e7fc792f1bd15b97cd022c5d 100644 --- a/sPuReMD/src/ffield.h +++ b/sPuReMD/src/ffield.h @@ -25,7 +25,7 @@ #include "reax_types.h" -void Read_Force_Field( FILE*, reax_interaction* ); +void Read_Force_Field( FILE *, reax_interaction *, int ); #endif diff --git a/sPuReMD/src/forces.c b/sPuReMD/src/forces.c index 4a1650c29c97ea0c9e6086960d5438cf9acead1c..e08760b1195677562152fa0846d9721dd8ca8083 100644 --- a/sPuReMD/src/forces.c +++ b/sPuReMD/src/forces.c @@ -1408,7 +1408,7 @@ void Estimate_Storage_Sizes( reax_system *system, control_params *control, far_nbrs = lists[FAR_NBRS]; - for ( i = 0; i < system->N; ++i ) + for ( i = 0; i < far_nbrs->n; ++i ) { atom_i = &system->atoms[i]; type_i = atom_i->type; diff --git a/sPuReMD/src/geo_tools.c b/sPuReMD/src/geo_tools.c index a60acddca39f52518eb2da8e2af523ec08a019b6..0fef6e0336a0e219f4c7ae17d9d3f56de47142f5 100644 --- a/sPuReMD/src/geo_tools.c +++ b/sPuReMD/src/geo_tools.c @@ -229,12 +229,14 @@ static int Read_Box_Info( reax_system *system, FILE *fp, int geo_format ) * fp: file pointer to open geometry file * geo_format: type of geometry file * */ -static void Count_Atoms( reax_system *system, FILE *fp, int geo_format ) +static int Count_Atoms( reax_system *system, FILE *fp, int geo_format ) { char line[MAX_LINE]; + int n; + + n = 0; fseek( fp, 0, SEEK_SET ); - system->N = 0; /* increment number of atoms for each line denoting an atom desc */ switch ( geo_format ) @@ -247,7 +249,7 @@ static void Count_Atoms( reax_system *system, FILE *fp, int geo_format ) if ( strncmp( line, "ATOM", 4 ) == 0 || strncmp( line, "HETATM", 6 ) == 0 ) { - system->N++; + ++n; } } @@ -259,7 +261,7 @@ static void Count_Atoms( reax_system *system, FILE *fp, int geo_format ) /* second line contains integer count * of the number of atoms */ - fscanf( fp, " %d", &system->N ); + fscanf( fp, " %d", &n ); break; @@ -269,20 +271,22 @@ static void Count_Atoms( reax_system *system, FILE *fp, int geo_format ) break; } - assert( system->N > 0 ); + assert( n > 0 ); #if defined(DEBUG) fprintf( stderr, "[INFO] Count_Atoms: " ); fprintf( stderr, "N = %d\n", system->N ); #endif + + return n; } void Read_Geo( const char * const geo_file, reax_system* system, control_params *control, - simulation_data *data, static_storage *workspace ) + simulation_data *data, static_storage *workspace, int first_run ) { FILE *geo; - int i, serial, top; + int i, n, serial, top; rvec x; char element[3], name[9]; reax_atom *atom; @@ -297,8 +301,12 @@ void Read_Geo( const char * const geo_file, reax_system* system, control_params } /* count atoms and allocate storage */ - Count_Atoms( system, geo, CUSTOM ); - PreAllocate_Space( system, control, workspace ); + n = Count_Atoms( system, geo, CUSTOM ); + if ( first_run == TRUE || n > system->N ) + { + PreAllocate_Space( system, control, workspace, n, first_run ); + } + system->N = n; /* parse atom info lines (3rd line and beyond) */ top = 0; @@ -331,9 +339,9 @@ void Read_Geo( const char * const geo_file, reax_system* system, control_params void Read_PDB( const char * const pdb_file, reax_system* system, control_params *control, - simulation_data *data, static_storage *workspace ) + simulation_data *data, static_storage *workspace, int first_run ) { - int i, c, c1, pdb_serial, top; + int i, n, c, c1, pdb_serial, top; FILE *pdb; char **tmp; char *s, *s1; @@ -361,8 +369,12 @@ void Read_PDB( const char * const pdb_file, reax_system* system, control_params exit( INVALID_GEO ); } - Count_Atoms( system, pdb, PDB ); - PreAllocate_Space( system, control, workspace ); + n = Count_Atoms( system, pdb, PDB ); + if ( first_run == TRUE || n > system->N ) + { + PreAllocate_Space( system, control, workspace, n, first_run ); + } + system->N = n; /* reset file pointer to beginning of file * and parse the PDB file */ @@ -601,7 +613,7 @@ void Write_PDB( reax_system* system, reax_list* bonds, simulation_data *data, void Read_BGF( const char * const bgf_file, reax_system* system, control_params *control, - simulation_data *data, static_storage *workspace ) + simulation_data *data, static_storage *workspace, int first_run ) { FILE *bgf; char **tokens; @@ -614,7 +626,7 @@ void Read_BGF( const char * const bgf_file, reax_system* system, control_params char chain_id; char s_a[12], s_b[12], s_c[12], s_alpha[12], s_beta[12], s_gamma[12]; char *endptr; - int i, atom_cnt, token_cnt, bgf_serial, ratom, crystx_found; + int i, n, atom_cnt, token_cnt, bgf_serial, ratom, crystx_found; endptr = NULL; ratom = 0; @@ -626,7 +638,7 @@ void Read_BGF( const char * const bgf_file, reax_system* system, control_params &tokens, MAX_TOKENS, MAX_TOKEN_LEN ); /* count number of atoms in the BGF file */ - system->N = 0; + n = 0; line[0] = 0; while ( fgets( line, MAX_LINE, bgf ) ) @@ -637,7 +649,7 @@ void Read_BGF( const char * const bgf_file, reax_system* system, control_params if ( strncmp( tokens[0], "ATOM", 4 ) == 0 || strncmp( tokens[0], "HETATM", 6 ) == 0 ) { - ++system->N; + ++n; } line[0] = 0; @@ -650,7 +662,11 @@ void Read_BGF( const char * const bgf_file, reax_system* system, control_params sfclose( bgf, "Read_BGF::bgf" ); - PreAllocate_Space( system, control, workspace ); + if ( first_run == TRUE || n > system->N ) + { + PreAllocate_Space( system, control, workspace, n, first_run ); + } + system->N = n; workspace->map_serials = scalloc( MAX_ATOM_ID, sizeof(int), "Read_BGF::workspace->map_serials" ); diff --git a/sPuReMD/src/geo_tools.h b/sPuReMD/src/geo_tools.h index b72c8bd1357d2bf4663070b1b9a7971dd0785ead..af91cb3c349e50c6c30b2191d8db2a943a8cf856 100644 --- a/sPuReMD/src/geo_tools.h +++ b/sPuReMD/src/geo_tools.h @@ -25,17 +25,17 @@ #include "reax_types.h" -void Read_Geo( const char * const, reax_system*, control_params*, - simulation_data*, static_storage* ); +void Read_Geo( const char * const, reax_system *, control_params *, + simulation_data *, static_storage *, int ); -void Read_PDB( const char * const, reax_system*, control_params*, - simulation_data*, static_storage* ); +void Read_PDB( const char * const, reax_system *, control_params *, + simulation_data *, static_storage *, int ); -void Read_BGF( const char * const, reax_system*, control_params*, - simulation_data*, static_storage* ); +void Read_BGF( const char * const, reax_system *, control_params *, + simulation_data *, static_storage *, int ); -void Write_PDB( reax_system*, reax_list*, simulation_data*, - control_params*, static_storage*, output_controls* ); +void Write_PDB( reax_system *, reax_list *, simulation_data *, + control_params *, static_storage *, output_controls * ); #endif diff --git a/sPuReMD/src/grid.c b/sPuReMD/src/grid.c index ede82a292d8fba1e0c19386a35da68bd7a508006..7e6d9b5fc4fb4c2b3f5bff11da92c50bbd19a007 100644 --- a/sPuReMD/src/grid.c +++ b/sPuReMD/src/grid.c @@ -38,9 +38,11 @@ static int Estimate_GCell_Population( reax_system* system ) for ( l = 0; l < system->N; l++ ) { - i = (int)(system->atoms[l].x[0] * g->inv_len[0]); - j = (int)(system->atoms[l].x[1] * g->inv_len[1]); - k = (int)(system->atoms[l].x[2] * g->inv_len[2]); + /* NOTE: this assumes the atom positions + * are within the simulation box boundaries */ + i = (int) (system->atoms[l].x[0] * g->inv_len[0]); + j = (int) (system->atoms[l].x[1] * g->inv_len[1]); + k = (int) (system->atoms[l].x[2] * g->inv_len[2]); g->top[i][j][k]++; // fprintf( stderr, "\tatom%-6d (%8.3f%8.3f%8.3f) --> (%3d%3d%3d)\n", @@ -67,109 +69,197 @@ static int Estimate_GCell_Population( reax_system* system ) } -static void Allocate_Space_for_Grid( reax_system *system ) +static void Allocate_Space_for_Grid( reax_system *system, int alloc ) { - int i, j, k, l; + int i, j, k, l, max_atoms; grid *g; g = &system->g; g->max_nbrs = (2 * g->spread[0] + 1) * (2 * g->spread[1] + 1) * (2 * g->spread[2] + 1) + 3; - /* allocate space for the new grid */ - g->atoms = (int****) scalloc( g->ncell[0], sizeof( int*** ), - "Allocate_Space_for_Grid::g->atoms" ); - g->top = (int***) scalloc( g->ncell[0], sizeof( int** ), - "Allocate_Space_for_Grid::g->top" ); - g->mark = (int***) scalloc( g->ncell[0], sizeof( int** ), - "Allocate_Space_for_Grid::g->mark" ); - g->start = (int***) scalloc( g->ncell[0], sizeof( int** ), - "Allocate_Space_for_Grid::g->start" ); - g->end = (int***) scalloc( g->ncell[0], sizeof( int** ), - "Allocate_Space_for_Grid::g->end" ); - g->nbrs = (ivec****) scalloc( g->ncell[0], sizeof( ivec*** ), - "Allocate_Space_for_Grid::g->nbrs" ); - g->nbrs_cp = (rvec****) scalloc( g->ncell[0], sizeof( rvec*** ), - "Allocate_Space_for_Grid::g->nbrs_cp" ); - - for ( i = 0; i < g->ncell[0]; i++ ) + if ( alloc == TRUE ) { - g->atoms[i] = (int***) scalloc( g->ncell[1], sizeof( int** ), - "Allocate_Space_for_Grid::g->atoms[i]" ); - g->top [i] = (int**) scalloc( g->ncell[1], sizeof( int* ), - "Allocate_Space_for_Grid::g->top[i]" ); - g->mark[i] = (int**) scalloc( g->ncell[1], sizeof( int* ), - "Allocate_Space_for_Grid::g->mark[i]" ); - g->start[i] = (int**) scalloc( g->ncell[1], sizeof( int* ), - "Allocate_Space_for_Grid::g->start[i]" ); - g->end[i] = (int**) scalloc( g->ncell[1], sizeof( int* ), - "Allocate_Space_for_Grid::g->end[i]" ); - g->nbrs[i] = (ivec***) scalloc( g->ncell[1], sizeof( ivec** ), - "Allocate_Space_for_Grid::g->nbrs[i]" ); - g->nbrs_cp[i] = (rvec***) scalloc( g->ncell[1], sizeof( rvec** ), - "Allocate_Space_for_Grid::g->nbrs_cp[i]" ); + /* allocate space for the new grid */ + g->atoms = (int****) scalloc( g->ncell_max[0], sizeof( int*** ), + "Allocate_Space_for_Grid::g->atoms" ); - for ( j = 0; j < g->ncell[1]; j++ ) + for ( i = 0; i < g->ncell_max[0]; i++ ) { - g->atoms[i][j] = (int**) scalloc( g->ncell[2], sizeof( int* ), - "Allocate_Space_for_Grid::g->atoms[i][j]" ); - g->top[i][j] = (int*) scalloc( g->ncell[2], sizeof( int ), - "Allocate_Space_for_Grid::g->top[i][j]" ); - g->mark[i][j] = (int*) scalloc( g->ncell[2], sizeof( int ), - "Allocate_Space_for_Grid::g->mark[i][j]" ); - g->start[i][j] = (int*) scalloc( g->ncell[2], sizeof( int ), - "Allocate_Space_for_Grid::g->start[i][j]" ); - g->end[i][j] = (int*) scalloc( g->ncell[2], sizeof( int ), - "Allocate_Space_for_Grid::g->end[i][j]" ); - g->nbrs[i][j] = (ivec**) scalloc( g->ncell[2], sizeof( ivec* ), - "Allocate_Space_for_Grid::g->nbrs[i][j]" ); - g->nbrs_cp[i][j] = (rvec**) scalloc( g->ncell[2], sizeof( rvec* ), - "Allocate_Space_for_Grid::g->nbrs_cp[i][j]" ); + g->atoms[i] = (int***) scalloc( g->ncell_max[1], sizeof( int** ), + "Allocate_Space_for_Grid::g->atoms[i]" ); - for ( k = 0; k < g->ncell[2]; k++ ) + for ( j = 0; j < g->ncell_max[1]; j++ ) + g->atoms[i][j] = (int**) scalloc( g->ncell_max[2], sizeof( int* ), + "Allocate_Space_for_Grid::g->atoms[i][j]" ); + + } + + g->top = (int***) scalloc( g->ncell_max[0], sizeof( int** ), + "Allocate_Space_for_Grid::g->top" ); + + for ( i = 0; i < g->ncell_max[0]; i++ ) + { + g->top[i] = (int**) scalloc( g->ncell_max[1], sizeof( int* ), + "Allocate_Space_for_Grid::g->top[i]" ); + + for ( j = 0; j < g->ncell_max[1]; j++ ) + g->top[i][j] = (int*) scalloc( g->ncell_max[2], sizeof( int ), + "Allocate_Space_for_Grid::g->top[i][j]" ); + } + + g->mark = (int***) scalloc( g->ncell_max[0], sizeof( int** ), + "Allocate_Space_for_Grid::g->mark" ); + + for ( i = 0; i < g->ncell_max[0]; i++ ) + { + g->mark[i] = (int**) scalloc( g->ncell_max[1], sizeof( int* ), + "Allocate_Space_for_Grid::g->mark[i]" ); + + for ( j = 0; j < g->ncell_max[1]; j++ ) + g->mark[i][j] = (int*) scalloc( g->ncell_max[2], sizeof( int ), + "Allocate_Space_for_Grid::g->mark[i][j]" ); + } + + g->start = (int***) scalloc( g->ncell_max[0], sizeof( int** ), + "Allocate_Space_for_Grid::g->start" ); + + for ( i = 0; i < g->ncell_max[0]; i++ ) + { + g->start[i] = (int**) scalloc( g->ncell_max[1], sizeof( int* ), + "Allocate_Space_for_Grid::g->start[i]" ); + + for ( j = 0; j < g->ncell_max[1]; j++ ) + g->start[i][j] = (int*) scalloc( g->ncell_max[2], sizeof( int ), + "Allocate_Space_for_Grid::g->start[i][j]" ); + } + + g->end = (int***) scalloc( g->ncell_max[0], sizeof( int** ), + "Allocate_Space_for_Grid::g->end" ); + + for ( i = 0; i < g->ncell_max[0]; i++ ) + { + g->end[i] = (int**) scalloc( g->ncell_max[1], sizeof( int* ), + "Allocate_Space_for_Grid::g->end[i]" ); + + for ( j = 0; j < g->ncell_max[1]; j++ ) + g->end[i][j] = (int*) scalloc( g->ncell_max[2], sizeof( int ), + "Allocate_Space_for_Grid::g->end[i][j]" ); + } + + g->nbrs = (ivec****) scalloc( g->ncell_max[0], sizeof( ivec*** ), + "Allocate_Space_for_Grid::g->nbrs" ); + + for ( i = 0; i < g->ncell_max[0]; i++ ) + { + g->nbrs[i] = (ivec***) scalloc( g->ncell_max[1], sizeof( ivec** ), + "Allocate_Space_for_Grid::g->nbrs[i]" ); + + for ( j = 0; j < g->ncell_max[1]; j++ ) + { + g->nbrs[i][j] = (ivec**) scalloc( g->ncell_max[2], sizeof( ivec* ), + "Allocate_Space_for_Grid::g->nbrs[i][j]" ); + + for ( k = 0; k < g->ncell_max[2]; k++ ) + g->nbrs[i][j][k] = (ivec*) smalloc( g->max_nbrs * sizeof( ivec ), + "Allocate_Space_for_Grid::g->nbrs[i][j]][k]" ); + } + } + + g->nbrs_cp = (rvec****) scalloc( g->ncell_max[0], sizeof( rvec*** ), + "Allocate_Space_for_Grid::g->nbrs_cp" ); + + for ( i = 0; i < g->ncell_max[0]; i++ ) + { + g->nbrs_cp[i] = (rvec***) scalloc( g->ncell_max[1], sizeof( rvec** ), + "Allocate_Space_for_Grid::g->nbrs_cp[i]" ); + + for ( j = 0; j < g->ncell_max[1]; j++ ) { + g->nbrs_cp[i][j] = (rvec**) scalloc( g->ncell_max[2], sizeof( rvec* ), + "Allocate_Space_for_Grid::g->nbrs_cp[i][j]" ); + + for ( k = 0; k < g->ncell_max[2]; k++ ) + g->nbrs_cp[i][j][k] = (rvec*) smalloc( g->max_nbrs * sizeof( rvec ), + "Allocate_Space_for_Grid::g->nbrs_cp[i][j]][k]" ); + } + } + } + + for ( i = 0; i < g->ncell[0]; i++ ) + for ( j = 0; j < g->ncell[1]; j++ ) + for ( k = 0; k < g->ncell[2]; k++ ) g->top[i][j][k] = 0; + + for ( i = 0; i < g->ncell[0]; i++ ) + for ( j = 0; j < g->ncell[1]; j++ ) + for ( k = 0; k < g->ncell[2]; k++ ) g->mark[i][j][k] = 0; + + for ( i = 0; i < g->ncell[0]; i++ ) + for ( j = 0; j < g->ncell[1]; j++ ) + for ( k = 0; k < g->ncell[2]; k++ ) g->start[i][j][k] = 0; + + for ( i = 0; i < g->ncell[0]; i++ ) + for ( j = 0; j < g->ncell[1]; j++ ) + for ( k = 0; k < g->ncell[2]; k++ ) g->end[i][j][k] = 0; - g->nbrs[i][j][k] = (ivec*) smalloc( g->max_nbrs * sizeof( ivec ), - "Allocate_Space_for_Grid::g->nbrs[i][j]][k]" ); - g->nbrs_cp[i][j][k] = (rvec*) smalloc( g->max_nbrs * sizeof( rvec ), - "Allocate_Space_for_Grid::g->nbrs_cp[i][j]][k]" ); + for ( i = 0; i < g->ncell[0]; i++ ) + for ( j = 0; j < g->ncell[1]; j++ ) + for ( k = 0; k < g->ncell[2]; k++ ) for ( l = 0; l < g->max_nbrs; ++l ) { g->nbrs[i][j][k][l][0] = -1; g->nbrs[i][j][k][l][1] = -1; g->nbrs[i][j][k][l][2] = -1; + } + for ( i = 0; i < g->ncell[0]; i++ ) + for ( j = 0; j < g->ncell[1]; j++ ) + for ( k = 0; k < g->ncell[2]; k++ ) + for ( l = 0; l < g->max_nbrs; ++l ) + { g->nbrs_cp[i][j][k][l][0] = -1.0; g->nbrs_cp[i][j][k][l][1] = -1.0; g->nbrs_cp[i][j][k][l][2] = -1.0; } - } - } - } - g->max_atoms = Estimate_GCell_Population( system ); + max_atoms = Estimate_GCell_Population( system ); - for ( i = 0; i < g->ncell[0]; i++ ) + if ( alloc == TRUE ) + { + g->max_atoms = MAX( max_atoms, g->max_atoms ); + + for ( i = 0; i < g->ncell_max[0]; i++ ) + for ( j = 0; j < g->ncell_max[1]; j++ ) + for ( k = 0; k < g->ncell_max[2]; k++ ) + g->atoms[i][j][k] = (int*) smalloc( g->max_atoms * sizeof( int ), + "Allocate_Space_for_Grid::g->atoms[i][j]][k]" ); + } + /* case: grid large enough but max. atoms per grid cells insufficient */ + else if ( g->max_atoms > 0 && g->max_atoms < max_atoms ) { + g->max_atoms = max_atoms; + + for ( i = 0; i < g->ncell_max[0]; i++ ) + for ( j = 0; j < g->ncell_max[1]; j++ ) + for ( k = 0; k < g->ncell_max[2]; k++ ) + sfree( g->atoms[i][j][k], "Allocate_Space_for_Grid::g->atoms[i][j]][k]" ); + + for ( i = 0; i < g->ncell_max[0]; i++ ) + for ( j = 0; j < g->ncell_max[1]; j++ ) + for ( k = 0; k < g->ncell_max[2]; k++ ) + g->atoms[i][j][k] = (int*) smalloc( g->max_atoms * sizeof( int ), + "Allocate_Space_for_Grid::g->atoms[i][j]][k]" ); + } + + for ( i = 0; i < g->ncell[0]; i++ ) for ( j = 0; j < g->ncell[1]; j++ ) - { for ( k = 0; k < g->ncell[2]; k++ ) - { - g->atoms[i][j][k] = (int*) smalloc( g->max_atoms * sizeof( int ), - "Allocate_Space_for_Grid::g->atoms[i][j]][k]" ); - for ( l = 0; l < g->max_atoms; ++l ) - { g->atoms[i][j][k][l] = -1; - } - } - } - } - } @@ -178,11 +268,11 @@ static void Deallocate_Grid_Space( grid *g ) int i, j, k; /* deallocate the old grid */ - for ( i = 0; i < g->ncell[0]; i++ ) + for ( i = 0; i < g->ncell_max[0]; i++ ) { - for ( j = 0; j < g->ncell[1]; j++ ) + for ( j = 0; j < g->ncell_max[1]; j++ ) { - for ( k = 0; k < g->ncell[2]; k++ ) + for ( k = 0; k < g->ncell_max[2]; k++ ) { sfree( g->atoms[i][j][k], "Deallocate_Grid_Space::g->atoms[i][j][k]" ); sfree( g->nbrs[i][j][k], "Deallocate_Grid_Space::g->nbrs[i][j][k]" ); @@ -372,36 +462,53 @@ static void Find_Neighbor_Grid_Cells( grid *g ) } -void Setup_Grid( reax_system* system ) +void Setup_Grid( reax_system* system, int first_run ) { - int d; - ivec ncell; + int d, alloc; grid *g; simulation_box *my_box; + alloc = FALSE; g = &system->g; my_box = &system->box; /* determine number of grid cells in each direction */ - ivec_rScale( ncell, 1.0 / g->cell_size, my_box->box_norms ); + ivec_rScale( g->ncell, 1.0 / g->cell_size, my_box->box_norms ); for ( d = 0; d < 3; ++d ) { - if ( ncell[d] <= 0 ) + if ( g->ncell[d] <= 0 ) { - ncell[d] = 1; + g->ncell[d] = 1; } } - /* find the number of grid cells */ - g->total = ncell[0] * ncell[1] * ncell[2]; - ivec_Copy( g->ncell, ncell ); + if ( first_run == TRUE ) + { + g->ncell_max[0] = (int) CEIL( SAFE_ZONE * g->ncell[0] ); + g->ncell_max[1] = (int) CEIL( SAFE_ZONE * g->ncell[1] ); + g->ncell_max[2] = (int) CEIL( SAFE_ZONE * g->ncell[2] ); + g->max_atoms = 0; + + alloc = TRUE; + } + else if ( first_run == FALSE && (g->ncell[0] > g->ncell_max[0] + || g->ncell[1] > g->ncell_max[1] || g->ncell[2] > g->ncell_max[2]) ) + { + Deallocate_Grid_Space( g ); + + g->ncell_max[0] = (int) CEIL( SAFE_ZONE * MAX( g->ncell[0], g->ncell_max[0] ) ); + g->ncell_max[1] = (int) CEIL( SAFE_ZONE * MAX( g->ncell[1], g->ncell_max[1] ) ); + g->ncell_max[2] = (int) CEIL( SAFE_ZONE * MAX( g->ncell[2], g->ncell_max[2] ) ); + + alloc = TRUE; + } /* compute cell lengths */ rvec_iDivide( g->len, my_box->box_norms, g->ncell ); rvec_Invert( g->inv_len, g->len ); - Allocate_Space_for_Grid( system ); + Allocate_Space_for_Grid( system, alloc ); Find_Neighbor_Grid_Cells( g ); #if defined(DEBUG_FOCUS) @@ -473,14 +580,13 @@ void Update_Grid( reax_system* system ) Deallocate_Grid_Space( g ); /* update number of grid cells */ - g->total = ncell[0] * ncell[1] * ncell[2]; ivec_Copy( g->ncell, ncell ); /* update cell lengths */ rvec_iDivide( g->len, my_box->box_norms, g->ncell ); rvec_Invert( g->inv_len, g->len ); - Allocate_Space_for_Grid( system ); + Allocate_Space_for_Grid( system, TRUE ); Find_Neighbor_Grid_Cells( g ); #if defined(DEBUG_FOCUS) @@ -539,9 +645,9 @@ void Bin_Atoms( reax_system* system, static_storage *workspace ) } /* reallocation check */ - if ( max_atoms >= (int)(g->max_atoms * SAFE_ZONE) ) + if ( max_atoms >= (int) CEIL( g->max_atoms * SAFE_ZONE ) ) { - workspace->realloc.gcell_atoms = MAX( (int)(max_atoms * SAFE_ZONE), + workspace->realloc.gcell_atoms = MAX( (int) CEIL( max_atoms * SAFE_ZONE ), MIN_GCELL_POPL ); } } diff --git a/sPuReMD/src/grid.h b/sPuReMD/src/grid.h index abd0f401bf44462682bd5003be40f63a4abfc7c7..cdc030a318af63e25d333698c9fe4f781d9b0084 100644 --- a/sPuReMD/src/grid.h +++ b/sPuReMD/src/grid.h @@ -25,13 +25,13 @@ #include "reax_types.h" -void Setup_Grid( reax_system* ); +void Setup_Grid( reax_system *, int ); -void Update_Grid( reax_system* ); +void Update_Grid( reax_system * ); -void Bin_Atoms( reax_system*, static_storage* ); +void Bin_Atoms( reax_system *, static_storage * ); -void Finalize_Grid( reax_system* ); +void Finalize_Grid( reax_system * ); void Cluster_Atoms( reax_system *, static_storage *, control_params * ); diff --git a/sPuReMD/src/init_md.c b/sPuReMD/src/init_md.c index 48b8bdef6a8b7dbb35df1bc3e8e4ef942b7b3e74..9809a3bfd57f19b6e48217b2d181bcaa812c290b 100644 --- a/sPuReMD/src/init_md.c +++ b/sPuReMD/src/init_md.c @@ -99,7 +99,7 @@ static void Generate_Initial_Velocities( reax_system *system, static void Init_System( reax_system *system, control_params *control, - simulation_data *data ) + simulation_data *data, int first_run ) { int i; rvec dx; @@ -110,7 +110,7 @@ static void Init_System( reax_system *system, control_params *control, } Compute_Total_Mass( system, data ); - Compute_Center_of_Mass( system, data, stderr ); + Compute_Center_of_Mass( system, data ); /* just fit the atoms to the periodic box */ if ( control->reposition_atoms == 0 ) @@ -154,17 +154,17 @@ static void Init_System( reax_system *system, control_params *control, Generate_Initial_Velocities( system, control, control->T_init ); } - Setup_Grid( system ); + Setup_Grid( system, first_run ); } static void Init_Simulation_Data( reax_system *system, control_params *control, simulation_data *data, output_controls *out_control, - evolve_function *Evolve ) + evolve_function *Evolve, int alloc ) { #if defined(_OPENMP) - if ( control->ensemble == sNPT || control->ensemble == iNPT - || control->ensemble == aNPT || control->compute_pressure == TRUE ) + if ( alloc == TRUE && (control->ensemble == sNPT || control->ensemble == iNPT + || control->ensemble == aNPT || control->compute_pressure == TRUE) ) { data->press_local = smalloc( sizeof( rtensor ) * control->num_threads, "Init_Simulation_Data::data->press_local" ); @@ -323,60 +323,66 @@ static void Init_Taper( control_params *control, static_storage *workspace ) static void Init_Workspace( reax_system *system, control_params *control, - static_storage *workspace ) + static_storage *workspace, int alloc ) { int i; - /* hydrogen bond list */ - workspace->hbond_index = smalloc( system->N * sizeof( int ), - "Init_Workspace::workspace->hbond_index" ); - - /* bond order related storage */ - workspace->total_bond_order = smalloc( system->N * sizeof( real ), - "Init_Workspace::workspace->bond_order" ); - workspace->Deltap = smalloc( system->N * sizeof( real ), - "Init_Workspace::workspace->Deltap" ); - workspace->Deltap_boc = smalloc( system->N * sizeof( real ), - "Init_Workspace::workspace->Deltap_boc" ); - workspace->dDeltap_self = smalloc( system->N * sizeof( rvec ), - "Init_Workspace::workspace->dDeltap_self" ); - - workspace->Delta = smalloc( system->N * sizeof( real ), - "Init_Workspace::workspace->Delta" ); - workspace->Delta_lp = smalloc( system->N * sizeof( real ), - "Init_Workspace::workspace->Delta_lp" ); - workspace->Delta_lp_temp = smalloc( system->N * sizeof( real ), - "Init_Workspace::workspace->Delta_lp_temp" ); - workspace->dDelta_lp = smalloc( system->N * sizeof( real ), - "Init_Workspace::workspace->dDelta_lp" ); - workspace->dDelta_lp_temp = smalloc( system->N * sizeof( real ), - "Init_Workspace::workspace->dDelta_lp_temp" ); - workspace->Delta_e = smalloc( system->N * sizeof( real ), - "Init_Workspace::workspace->Delta_e" ); - workspace->Delta_boc = smalloc( system->N * sizeof( real ), - "Init_Workspace::workspace->Delta_boc" ); - workspace->nlp = smalloc( system->N * sizeof( real ), - "Init_Workspace::workspace->nlp" ); - workspace->nlp_temp = smalloc( system->N * sizeof( real ), - "Init_Workspace::workspace->nlp_temp" ); - workspace->Clp = smalloc( system->N * sizeof( real ), - "Init_Workspace::workspace->Clp" ); - workspace->CdDelta = smalloc( system->N * sizeof( real ), - "Init_Workspace::workspace->CdDelta" ); - workspace->vlpex = smalloc( system->N * sizeof( real ), - "Init_Workspace::workspace->vlpex" ); + if ( alloc == TRUE ) + { + /* hydrogen bond list */ + workspace->hbond_index = smalloc( system->N_max * sizeof( int ), + "Init_Workspace::workspace->hbond_index" ); + + /* bond order related storage */ + workspace->total_bond_order = smalloc( system->N_max * sizeof( real ), + "Init_Workspace::workspace->bond_order" ); + workspace->Deltap = smalloc( system->N_max * sizeof( real ), + "Init_Workspace::workspace->Deltap" ); + workspace->Deltap_boc = smalloc( system->N_max * sizeof( real ), + "Init_Workspace::workspace->Deltap_boc" ); + workspace->dDeltap_self = smalloc( system->N_max * sizeof( rvec ), + "Init_Workspace::workspace->dDeltap_self" ); + + workspace->Delta = smalloc( system->N_max * sizeof( real ), + "Init_Workspace::workspace->Delta" ); + workspace->Delta_lp = smalloc( system->N_max * sizeof( real ), + "Init_Workspace::workspace->Delta_lp" ); + workspace->Delta_lp_temp = smalloc( system->N_max * sizeof( real ), + "Init_Workspace::workspace->Delta_lp_temp" ); + workspace->dDelta_lp = smalloc( system->N_max * sizeof( real ), + "Init_Workspace::workspace->dDelta_lp" ); + workspace->dDelta_lp_temp = smalloc( system->N_max * sizeof( real ), + "Init_Workspace::workspace->dDelta_lp_temp" ); + workspace->Delta_e = smalloc( system->N_max * sizeof( real ), + "Init_Workspace::workspace->Delta_e" ); + workspace->Delta_boc = smalloc( system->N_max * sizeof( real ), + "Init_Workspace::workspace->Delta_boc" ); + workspace->nlp = smalloc( system->N_max * sizeof( real ), + "Init_Workspace::workspace->nlp" ); + workspace->nlp_temp = smalloc( system->N_max * sizeof( real ), + "Init_Workspace::workspace->nlp_temp" ); + workspace->Clp = smalloc( system->N_max * sizeof( real ), + "Init_Workspace::workspace->Clp" ); + workspace->CdDelta = smalloc( system->N_max * sizeof( real ), + "Init_Workspace::workspace->CdDelta" ); + workspace->vlpex = smalloc( system->N_max * sizeof( real ), + "Init_Workspace::workspace->vlpex" ); + } /* charge method storage */ switch ( control->charge_method ) { case QEQ_CM: system->N_cm = system->N; + 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; break; case ACKS2_CM: system->N_cm = 2 * system->N + 2; + system->N_cm_max = 2 * system->N_max + 2; break; default: fprintf( stderr, "[ERROR] Unknown charge method type. Terminating...\n" ); @@ -384,44 +390,47 @@ static void Init_Workspace( reax_system *system, control_params *control, break; } - /* sparse matrices */ - workspace->H = NULL; - workspace->H_full = NULL; - workspace->H_sp = NULL; - workspace->H_p = NULL; - workspace->H_spar_patt = NULL; - workspace->H_spar_patt_full = NULL; - workspace->H_app_inv = NULL; - workspace->L = NULL; - workspace->U = NULL; - workspace->Hdia_inv = NULL; - if ( control->cm_solver_pre_comp_type == ICHOLT_PC - || (control->cm_solver_pre_comp_type == ILUT_PC && control->cm_solver_pre_comp_droptol > 0.0 ) - || control->cm_solver_pre_comp_type == ILUTP_PC - || control->cm_solver_pre_comp_type == FG_ILUT_PC ) - { - workspace->droptol = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->droptol" ); - } - - workspace->b_s = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->b_s" ); - workspace->b_t = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->b_t" ); - workspace->b_prc = scalloc( system->N_cm * 2, sizeof( real ), - "Init_Workspace::workspace->b_prc" ); - workspace->b_prm = scalloc( system->N_cm * 2, sizeof( real ), - "Init_Workspace::workspace->b_prm" ); - workspace->s = scalloc( 5, sizeof( real* ), - "Init_Workspace::workspace->s" ); - workspace->t = scalloc( 5, sizeof( real* ), - "Init_Workspace::workspace->t" ); - for ( i = 0; i < 5; ++i ) - { - workspace->s[i] = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->s[i]" ); - workspace->t[i] = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->t[i]" ); + if ( alloc == TRUE ) + { + /* sparse matrices */ + workspace->H = NULL; + workspace->H_full = NULL; + workspace->H_sp = NULL; + workspace->H_p = NULL; + workspace->H_spar_patt = NULL; + workspace->H_spar_patt_full = NULL; + workspace->H_app_inv = NULL; + workspace->L = NULL; + workspace->U = NULL; + workspace->Hdia_inv = NULL; + if ( control->cm_solver_pre_comp_type == ICHOLT_PC + || (control->cm_solver_pre_comp_type == ILUT_PC && control->cm_solver_pre_comp_droptol > 0.0 ) + || control->cm_solver_pre_comp_type == ILUTP_PC + || control->cm_solver_pre_comp_type == FG_ILUT_PC ) + { + workspace->droptol = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->droptol" ); + } + + workspace->b_s = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->b_s" ); + workspace->b_t = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->b_t" ); + workspace->b_prc = scalloc( system->N_cm_max * 2, sizeof( real ), + "Init_Workspace::workspace->b_prc" ); + workspace->b_prm = scalloc( system->N_cm_max * 2, sizeof( real ), + "Init_Workspace::workspace->b_prm" ); + workspace->s = scalloc( 5, sizeof( real* ), + "Init_Workspace::workspace->s" ); + workspace->t = scalloc( 5, sizeof( real* ), + "Init_Workspace::workspace->t" ); + for ( i = 0; i < 5; ++i ) + { + workspace->s[i] = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->s[i]" ); + workspace->t[i] = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->t[i]" ); + } } switch ( control->charge_method ) @@ -469,274 +478,283 @@ static void Init_Workspace( reax_system *system, control_params *control, break; } - switch ( control->cm_solver_type ) + if ( alloc == TRUE ) { - case GMRES_S: - case GMRES_H_S: - workspace->y = scalloc( control->cm_solver_restart + 1, sizeof( real ), - "Init_Workspace::workspace->y" ); - workspace->z = scalloc( control->cm_solver_restart + 1, sizeof( real ), - "Init_Workspace::workspace->z" ); - workspace->g = scalloc( control->cm_solver_restart + 1, sizeof( real ), - "Init_Workspace::workspace->g" ); - workspace->h = scalloc( control->cm_solver_restart + 1, sizeof( real*), - "Init_Workspace::workspace->h" ); - workspace->hs = scalloc( control->cm_solver_restart + 1, sizeof( real ), - "Init_Workspace::workspace->hs" ); - workspace->hc = scalloc( control->cm_solver_restart + 1, sizeof( real ), - "Init_Workspace::workspace->hc" ); - workspace->rn = scalloc( control->cm_solver_restart + 1, sizeof( real*), - "Init_Workspace::workspace->rn" ); - workspace->v = scalloc( control->cm_solver_restart + 1, sizeof( real*), - "Init_Workspace::workspace->v" ); - - for ( i = 0; i < control->cm_solver_restart + 1; ++i ) - { - workspace->h[i] = scalloc( control->cm_solver_restart + 1, sizeof( real ), - "Init_Workspace::workspace->h[i]" ); - workspace->rn[i] = scalloc( system->N_cm * 2, sizeof( real ), - "Init_Workspace::workspace->rn[i]" ); - workspace->v[i] = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->v[i]" ); - } - - workspace->r = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->r" ); - workspace->d = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->d" ); - workspace->q = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->q" ); - workspace->p = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->p" ); - break; - - case CG_S: - workspace->r = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->r" ); - workspace->d = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->d" ); - workspace->q = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->q" ); - workspace->p = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->p" ); - break; - - case SDM_S: - workspace->r = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->r" ); - workspace->d = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->d" ); - workspace->q = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->q" ); - break; - - case BiCGStab_S: - workspace->r = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->r" ); - workspace->r_hat = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->r_hat" ); - workspace->d = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->d" ); - workspace->q = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->q" ); - workspace->q_hat = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->q_hat" ); - workspace->p = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->p" ); - workspace->y = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->y" ); - workspace->z = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->z" ); - workspace->g = scalloc( system->N_cm, sizeof( real ), - "Init_Workspace::workspace->g" ); - break; - - default: - fprintf( stderr, "[ERROR] Unknown charge method linear solver type. Terminating...\n" ); - exit( INVALID_INPUT ); - break; - } + switch ( control->cm_solver_type ) + { + case GMRES_S: + case GMRES_H_S: + workspace->y = scalloc( control->cm_solver_restart + 1, sizeof( real ), + "Init_Workspace::workspace->y" ); + workspace->z = scalloc( control->cm_solver_restart + 1, sizeof( real ), + "Init_Workspace::workspace->z" ); + workspace->g = scalloc( control->cm_solver_restart + 1, sizeof( real ), + "Init_Workspace::workspace->g" ); + workspace->h = scalloc( control->cm_solver_restart + 1, sizeof( real*), + "Init_Workspace::workspace->h" ); + workspace->hs = scalloc( control->cm_solver_restart + 1, sizeof( real ), + "Init_Workspace::workspace->hs" ); + workspace->hc = scalloc( control->cm_solver_restart + 1, sizeof( real ), + "Init_Workspace::workspace->hc" ); + workspace->rn = scalloc( control->cm_solver_restart + 1, sizeof( real*), + "Init_Workspace::workspace->rn" ); + workspace->v = scalloc( control->cm_solver_restart + 1, sizeof( real*), + "Init_Workspace::workspace->v" ); + + for ( i = 0; i < control->cm_solver_restart + 1; ++i ) + { + workspace->h[i] = scalloc( control->cm_solver_restart + 1, sizeof( real ), + "Init_Workspace::workspace->h[i]" ); + workspace->rn[i] = scalloc( system->N_cm_max * 2, sizeof( real ), + "Init_Workspace::workspace->rn[i]" ); + workspace->v[i] = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->v[i]" ); + } + + workspace->r = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->r" ); + workspace->d = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->d" ); + workspace->q = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->q" ); + workspace->p = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->p" ); + break; + + case CG_S: + workspace->r = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->r" ); + workspace->d = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->d" ); + workspace->q = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->q" ); + workspace->p = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->p" ); + break; + + case SDM_S: + workspace->r = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->r" ); + workspace->d = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->d" ); + workspace->q = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->q" ); + break; + + case BiCGStab_S: + workspace->r = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->r" ); + workspace->r_hat = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->r_hat" ); + workspace->d = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->d" ); + workspace->q = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->q" ); + workspace->q_hat = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->q_hat" ); + workspace->p = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->p" ); + workspace->y = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->y" ); + workspace->z = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->z" ); + workspace->g = scalloc( system->N_cm_max, sizeof( real ), + "Init_Workspace::workspace->g" ); + break; + + default: + fprintf( stderr, "[ERROR] Unknown charge method linear solver type. Terminating...\n" ); + exit( INVALID_INPUT ); + break; + } - /* SpMV related */ #if defined(_OPENMP) - workspace->b_local = smalloc( control->num_threads * system->N_cm * sizeof(real), - "Init_Workspace::b_local" ); + /* SpMV related */ + workspace->b_local = smalloc( control->num_threads * system->N_cm_max * sizeof(real), + "Init_Workspace::b_local" ); #endif + } /* level scheduling related */ workspace->levels_L = 1; workspace->levels_U = 1; - if ( control->cm_solver_pre_app_type == TRI_SOLVE_LEVEL_SCHED_PA || - control->cm_solver_pre_app_type == TRI_SOLVE_GC_PA ) + if ( alloc == TRUE ) { - workspace->row_levels_L = smalloc( system->N_cm * sizeof(unsigned int), - "Init_Workspace::row_levels_L" ); - workspace->level_rows_L = smalloc( system->N_cm * sizeof(unsigned int), - "Init_Workspace::level_rows_L" ); - workspace->level_rows_cnt_L = smalloc( (system->N_cm + 1) * sizeof(unsigned int), - "Init_Workspace::level_rows_cnt_L" ); - workspace->row_levels_U = smalloc( system->N_cm * sizeof(unsigned int), - "Init_Workspace::row_levels_U" ); - workspace->level_rows_U = smalloc( system->N_cm * sizeof(unsigned int), - "Init_Workspace::level_rows_U" ); - workspace->level_rows_cnt_U = smalloc( (system->N_cm + 1) * sizeof(unsigned int), - "Init_Workspace::level_rows_cnt_U" ); - workspace->top = smalloc( (system->N_cm + 1) * sizeof(unsigned int), - "Init_Workspace::top" ); - } - else - { - workspace->row_levels_L = NULL; - workspace->level_rows_L = NULL; - workspace->level_rows_cnt_L = NULL; - workspace->row_levels_U = NULL; - workspace->level_rows_U = NULL; - workspace->level_rows_cnt_U = NULL; - workspace->top = NULL; + if ( control->cm_solver_pre_app_type == TRI_SOLVE_LEVEL_SCHED_PA || + control->cm_solver_pre_app_type == TRI_SOLVE_GC_PA ) + { + workspace->row_levels_L = smalloc( system->N_cm_max * sizeof(unsigned int), + "Init_Workspace::row_levels_L" ); + workspace->level_rows_L = smalloc( system->N_cm_max * sizeof(unsigned int), + "Init_Workspace::level_rows_L" ); + workspace->level_rows_cnt_L = smalloc( (system->N_cm_max + 1) * sizeof(unsigned int), + "Init_Workspace::level_rows_cnt_L" ); + workspace->row_levels_U = smalloc( system->N_cm_max * sizeof(unsigned int), + "Init_Workspace::row_levels_U" ); + workspace->level_rows_U = smalloc( system->N_cm_max * sizeof(unsigned int), + "Init_Workspace::level_rows_U" ); + workspace->level_rows_cnt_U = smalloc( (system->N_cm_max + 1) * sizeof(unsigned int), + "Init_Workspace::level_rows_cnt_U" ); + workspace->top = smalloc( (system->N_cm_max + 1) * sizeof(unsigned int), + "Init_Workspace::top" ); + } + else + { + workspace->row_levels_L = NULL; + workspace->level_rows_L = NULL; + workspace->level_rows_cnt_L = NULL; + workspace->row_levels_U = NULL; + workspace->level_rows_U = NULL; + workspace->level_rows_cnt_U = NULL; + workspace->top = NULL; + } } /* graph coloring related */ workspace->recolor_cnt = 0; - if ( control->cm_solver_pre_app_type == TRI_SOLVE_GC_PA ) - { - workspace->color = smalloc( sizeof(unsigned int) * system->N_cm, - "Init_Workspace::color" ); - workspace->to_color = smalloc( sizeof(unsigned int) * system->N_cm, - "Init_Workspace::to_color" ); - workspace->conflict = smalloc( sizeof(unsigned int) * system->N_cm, - "setup_graph_coloring::conflict" ); - workspace->conflict_cnt = smalloc( sizeof(unsigned int) * (control->num_threads + 1), - "Init_Workspace::conflict_cnt" ); - workspace->recolor = smalloc( sizeof(unsigned int) * system->N_cm, - "Init_Workspace::recolor" ); - workspace->color_top = smalloc( sizeof(unsigned int) * (system->N_cm + 1), - "Init_Workspace::color_top" ); - workspace->permuted_row_col = smalloc( sizeof(unsigned int) * system->N_cm, - "Init_Workspace::premuted_row_col" ); - workspace->permuted_row_col_inv = smalloc( sizeof(unsigned int) * system->N_cm, - "Init_Workspace::premuted_row_col_inv" ); - } - else + if ( alloc == TRUE ) { - workspace->color = NULL; - workspace->to_color = NULL; - workspace->conflict = NULL; - workspace->conflict_cnt = NULL; - workspace->recolor = NULL; - workspace->color_top = NULL; - workspace->permuted_row_col = NULL; - workspace->permuted_row_col_inv = NULL; - } + if ( control->cm_solver_pre_app_type == TRI_SOLVE_GC_PA ) + { + workspace->color = smalloc( sizeof(unsigned int) * system->N_cm_max, + "Init_Workspace::color" ); + workspace->to_color = smalloc( sizeof(unsigned int) * system->N_cm_max, + "Init_Workspace::to_color" ); + workspace->conflict = smalloc( sizeof(unsigned int) * system->N_cm_max, + "setup_graph_coloring::conflict" ); + workspace->conflict_cnt = smalloc( sizeof(unsigned int) * (control->num_threads + 1), + "Init_Workspace::conflict_cnt" ); + workspace->recolor = smalloc( sizeof(unsigned int) * system->N_cm_max, + "Init_Workspace::recolor" ); + workspace->color_top = smalloc( sizeof(unsigned int) * (system->N_cm_max + 1), + "Init_Workspace::color_top" ); + workspace->permuted_row_col = smalloc( sizeof(unsigned int) * system->N_cm_max, + "Init_Workspace::premuted_row_col" ); + workspace->permuted_row_col_inv = smalloc( sizeof(unsigned int) * system->N_cm_max, + "Init_Workspace::premuted_row_col_inv" ); + } + else + { + workspace->color = NULL; + workspace->to_color = NULL; + workspace->conflict = NULL; + workspace->conflict_cnt = NULL; + workspace->recolor = NULL; + workspace->color_top = NULL; + workspace->permuted_row_col = NULL; + workspace->permuted_row_col_inv = NULL; + } - /* graph coloring related OR ILUTP preconditioner */ - if ( control->cm_solver_pre_app_type == TRI_SOLVE_GC_PA - || control->cm_solver_pre_comp_type == ILUTP_PC ) - { - workspace->y_p = smalloc( sizeof(real) * system->N_cm, "Init_Workspace::y_p" ); - workspace->x_p = smalloc( sizeof(real) * system->N_cm, "Init_Workspace::x_p" ); - } - else - { - workspace->y_p = NULL; - workspace->x_p = NULL; - } + /* graph coloring related OR ILUTP preconditioner */ + if ( control->cm_solver_pre_app_type == TRI_SOLVE_GC_PA + || control->cm_solver_pre_comp_type == ILUTP_PC ) + { + workspace->y_p = smalloc( sizeof(real) * system->N_cm_max, "Init_Workspace::y_p" ); + workspace->x_p = smalloc( sizeof(real) * system->N_cm_max, "Init_Workspace::x_p" ); + } + else + { + workspace->y_p = NULL; + workspace->x_p = NULL; + } - /* Jacobi iteration related */ - if ( control->cm_solver_pre_app_type == JACOBI_ITER_PA ) - { - workspace->Dinv_L = smalloc( sizeof(real) * system->N_cm, - "Init_Workspace::Dinv_L" ); - workspace->Dinv_U = smalloc( sizeof(real) * system->N_cm, - "Init_Workspace::Dinv_U" ); - workspace->Dinv_b = smalloc( sizeof(real) * system->N_cm, - "Init_Workspace::Dinv_b" ); - workspace->rp = smalloc( sizeof(real) * system->N_cm, - "Init_Workspace::rp" ); - workspace->rp2 = smalloc( sizeof(real) * system->N_cm, - "Init_Workspace::rp2" ); - } - else - { - workspace->Dinv_L = NULL; - workspace->Dinv_U = NULL; - workspace->Dinv_b = NULL; - workspace->rp = NULL; - workspace->rp2 = NULL; - } + /* Jacobi iteration related */ + if ( control->cm_solver_pre_app_type == JACOBI_ITER_PA ) + { + workspace->Dinv_L = smalloc( sizeof(real) * system->N_cm_max, + "Init_Workspace::Dinv_L" ); + workspace->Dinv_U = smalloc( sizeof(real) * system->N_cm_max, + "Init_Workspace::Dinv_U" ); + workspace->Dinv_b = smalloc( sizeof(real) * system->N_cm_max, + "Init_Workspace::Dinv_b" ); + workspace->rp = smalloc( sizeof(real) * system->N_cm_max, + "Init_Workspace::rp" ); + workspace->rp2 = smalloc( sizeof(real) * system->N_cm_max, + "Init_Workspace::rp2" ); + } + else + { + workspace->Dinv_L = NULL; + workspace->Dinv_U = NULL; + workspace->Dinv_b = NULL; + workspace->rp = NULL; + workspace->rp2 = NULL; + } - /* ILUTP preconditioner related */ - if ( control->cm_solver_pre_comp_type == ILUTP_PC ) - { - workspace->perm_ilutp = smalloc( sizeof( int ) * system->N_cm, - "Init_Workspace::workspace->perm_ilutp" ); - } - else - { - workspace->perm_ilutp = NULL; - } + /* ILUTP preconditioner related */ + if ( control->cm_solver_pre_comp_type == ILUTP_PC ) + { + workspace->perm_ilutp = smalloc( sizeof( int ) * system->N_cm_max, + "Init_Workspace::workspace->perm_ilutp" ); + } + else + { + workspace->perm_ilutp = NULL; + } - /* integrator storage */ - workspace->a = smalloc( system->N * sizeof( rvec ), - "Init_Workspace::workspace->a" ); - workspace->f_old = smalloc( system->N * sizeof( rvec ), - "Init_Workspace::workspace->f_old" ); - workspace->v_const = smalloc( system->N * sizeof( rvec ), - "Init_Workspace::workspace->v_const" ); + /* integrator storage */ + workspace->a = smalloc( system->N_max * sizeof( rvec ), + "Init_Workspace::workspace->a" ); + workspace->f_old = smalloc( system->N_max * sizeof( rvec ), + "Init_Workspace::workspace->f_old" ); + workspace->v_const = smalloc( system->N_max * sizeof( rvec ), + "Init_Workspace::workspace->v_const" ); #if defined(_OPENMP) - workspace->f_local = smalloc( control->num_threads * system->N * sizeof( rvec ), - "Init_Workspace::workspace->f_local" ); + workspace->f_local = smalloc( control->num_threads * system->N_max * sizeof( rvec ), + "Init_Workspace::workspace->f_local" ); #endif - /* storage for analysis */ - if ( control->molec_anal || control->diffusion_coef ) - { - workspace->mark = scalloc( system->N, sizeof(int), - "Init_Workspace::workspace->mark" ); - workspace->old_mark = scalloc( system->N, sizeof(int), - "Init_Workspace::workspace->old_mark" ); - } - else - { - workspace->mark = workspace->old_mark = NULL; - } + /* storage for analysis */ + if ( control->molec_anal || control->diffusion_coef ) + { + workspace->mark = scalloc( system->N_max, sizeof(int), + "Init_Workspace::workspace->mark" ); + workspace->old_mark = scalloc( system->N_max, sizeof(int), + "Init_Workspace::workspace->old_mark" ); + } + else + { + workspace->mark = workspace->old_mark = NULL; + } - if ( control->diffusion_coef ) - { - workspace->x_old = scalloc( system->N, sizeof( rvec ), - "Init_Workspace::workspace->x_old" ); - } - else - { - workspace->x_old = NULL; + if ( control->diffusion_coef ) + { + workspace->x_old = scalloc( system->N_max, sizeof( rvec ), + "Init_Workspace::workspace->x_old" ); + } + else + { + workspace->x_old = NULL; + } } #if defined(TEST_FORCES) - workspace->dDelta = smalloc( system->N * sizeof( rvec ), + workspace->dDelta = smalloc( system->N_max * sizeof( rvec ), "Init_Workspace::workspace->dDelta" ); - workspace->f_ele = smalloc( system->N * sizeof( rvec ), + workspace->f_ele = smalloc( system->N_max * sizeof( rvec ), "Init_Workspace::workspace->f_ele" ); - workspace->f_vdw = smalloc( system->N * sizeof( rvec ), + workspace->f_vdw = smalloc( system->N_max * sizeof( rvec ), "Init_Workspace::workspace->f_vdw" ); - workspace->f_be = smalloc( system->N * sizeof( rvec ), + workspace->f_be = smalloc( system->N_max * sizeof( rvec ), "Init_Workspace::workspace->f_be" ); - workspace->f_lp = smalloc( system->N * sizeof( rvec ), + workspace->f_lp = smalloc( system->N_max * sizeof( rvec ), "Init_Workspace::workspace->f_lp" ); - workspace->f_ov = smalloc( system->N * sizeof( rvec ), + workspace->f_ov = smalloc( system->N_max * sizeof( rvec ), "Init_Workspace::workspace->f_ov" ); - workspace->f_un = smalloc( system->N * sizeof( rvec ), + workspace->f_un = smalloc( system->N_max * sizeof( rvec ), "Init_Workspace::workspace->f_un" ); - workspace->f_ang = smalloc( system->N * sizeof( rvec ), + workspace->f_ang = smalloc( system->N_max * sizeof( rvec ), "Init_Workspace::workspace->f_ang" ); - workspace->f_coa = smalloc( system->N * sizeof( rvec ), + workspace->f_coa = smalloc( system->N_max * sizeof( rvec ), "Init_Workspace::workspace->f_coa" ); - workspace->f_pen = smalloc( system->N * sizeof( rvec ), + workspace->f_pen = smalloc( system->N_max * sizeof( rvec ), "Init_Workspace::workspace->f_pen" ); - workspace->f_hb = smalloc( system->N * sizeof( rvec ), + workspace->f_hb = smalloc( system->N_max * sizeof( rvec ), "Init_Workspace::workspace->f_hb" ); - workspace->f_tor = smalloc( system->N * sizeof( rvec ), + workspace->f_tor = smalloc( system->N_max * sizeof( rvec ), "Init_Workspace::workspace->f_tor" ); - workspace->f_con = smalloc( system->N * sizeof( rvec ), + workspace->f_con = smalloc( system->N_max * sizeof( rvec ), "Init_Workspace::workspace->f_con" ); #endif @@ -756,22 +774,27 @@ static void Init_Workspace( reax_system *system, control_params *control, static void Init_Lists( reax_system *system, control_params *control, simulation_data *data, static_storage *workspace, - reax_list **lists, output_controls *out_control ) + reax_list **lists, output_controls *out_control, + int first_run, int alloc ) { - int i, num_nbrs, num_bonds, num_3body, Htop, max_nnz; + int i, num_nbrs, num_bonds, num_hbonds, num_3body, Htop, max_nnz; int *hb_top, *bond_top; -#if defined(DEBUG_FOCUS) - int num_hbonds; -#endif num_nbrs = Estimate_Num_Neighbors( system, control, workspace, lists ); - Make_List( system->N, num_nbrs, TYP_FAR_NEIGHBOR, lists[FAR_NBRS] ); - -#if defined(DEBUG_FOCUS) - fprintf( stderr, "memory allocated: far_nbrs = %ldMB\n", - num_nbrs * sizeof(far_neighbor_data) / (1024 * 1024) ); -#endif + if ( first_run == TRUE ) + { + Make_List( system->N, system->N_max, num_nbrs, TYP_FAR_NEIGHBOR, lists[FAR_NBRS] ); + } + else if ( alloc == TRUE || lists[FAR_NBRS]->total_intrs < num_nbrs ) + { + Delete_List( TYP_FAR_NEIGHBOR, lists[FAR_NBRS] ); + Make_List( system->N, system->N_max, num_nbrs, TYP_FAR_NEIGHBOR, lists[FAR_NBRS] ); + } + else + { + lists[FAR_NBRS]->n = system->N; + } Generate_Neighbor_Lists( system, control, data, workspace, lists, out_control ); @@ -800,12 +823,41 @@ static void Init_Lists( reax_system *system, control_params *control, break; } - Allocate_Matrix( &workspace->H, system->N_cm, max_nnz ); - /* TODO: better estimate for H_sp? - * If so, need to refactor Estimate_Storage_Sizes - * to use various cut-off distances as parameters - * (non-bonded, hydrogen, 3body, etc.) */ - Allocate_Matrix( &workspace->H_sp, system->N_cm, max_nnz ); + if ( first_run == TRUE ) + { + Allocate_Matrix( &workspace->H, system->N_cm, system->N_cm_max, max_nnz ); + } + else if ( alloc == TRUE || workspace->H->m < max_nnz ) + { + Deallocate_Matrix( workspace->H ); + Allocate_Matrix( &workspace->H, system->N_cm, system->N_cm_max, max_nnz ); + } + else + { + workspace->H->n = system->N_cm; + } + + if ( first_run == TRUE ) + { + /* TODO: better estimate for H_sp? + * If so, need to refactor Estimate_Storage_Sizes + * to use various cut-off distances as parameters + * (non-bonded, hydrogen, 3body, etc.) */ + Allocate_Matrix( &workspace->H_sp, system->N_cm, system->N_cm_max, max_nnz ); + } + else if ( alloc == TRUE || workspace->H_sp->m < max_nnz ) + { + Deallocate_Matrix( workspace->H_sp ); + /* TODO: better estimate for H_sp? + * If so, need to refactor Estimate_Storage_Sizes + * to use various cut-off distances as parameters + * (non-bonded, hydrogen, 3body, etc.) */ + Allocate_Matrix( &workspace->H_sp, system->N_cm, system->N_cm_max, max_nnz ); + } + else + { + workspace->H_sp->n = system->N_cm; + } workspace->num_H = 0; if ( control->hbond_cut > 0.0 ) @@ -829,21 +881,64 @@ static void Init_Lists( reax_system *system, control_params *control, } else { - Allocate_HBond_List( system->N, workspace->num_H, workspace->hbond_index, - hb_top, lists[HBONDS] ); + num_hbonds = 0; + for ( i = 0; i < system->N; ++i ) + { + num_hbonds += hb_top[i]; + } + + if ( first_run == TRUE ) + { + workspace->num_H_max = (int) CEIL( SAFE_ZONE * workspace->num_H ); + + Allocate_HBond_List( system->N, workspace->num_H, workspace->num_H_max, + workspace->hbond_index, hb_top, lists[HBONDS] ); + } + else if ( workspace->num_H_max < workspace->num_H + || lists[HBONDS]->total_intrs < num_hbonds ) + { + if ( workspace->num_H_max < workspace->num_H ) + { + workspace->num_H_max = (int) CEIL( SAFE_ZONE * workspace->num_H ); + } + + Delete_List( TYP_HBOND, lists[HBONDS] ); + Allocate_HBond_List( system->N, workspace->num_H, workspace->num_H_max, + workspace->hbond_index, hb_top, lists[HBONDS] ); + } + else + { + lists[HBONDS]->n = workspace->num_H; + } } #if defined(DEBUG_FOCUS) - num_hbonds = hb_top[system->N - 1]; fprintf( stderr, "estimated storage - num_hbonds: %d\n", num_hbonds ); fprintf( stderr, "memory allocated: hbonds = %ldMB\n", num_hbonds * sizeof(hbond_data) / (1024 * 1024) ); #endif } + num_bonds = 0; + for ( i = 0; i < system->N; ++i ) + { + num_bonds += bond_top[i]; + } + /* bonds list */ - Allocate_Bond_List( system->N, bond_top, lists[BONDS] ); - num_bonds = bond_top[system->N - 1]; + if ( first_run == TRUE ) + { + Allocate_Bond_List( system->N, system->N_max, bond_top, lists[BONDS] ); + } + else if ( alloc == TRUE || lists[BONDS]->total_intrs < num_bonds ) + { + Delete_List( TYP_BOND, lists[BONDS] ); + Allocate_Bond_List( system->N, system->N_max, bond_top, lists[BONDS] ); + } + else + { + lists[BONDS]->n = system->N; + } #if defined(DEBUG_FOCUS) fprintf( stderr, "estimated storage - num_bonds: %d\n", num_bonds ); @@ -852,7 +947,29 @@ static void Init_Lists( reax_system *system, control_params *control, #endif /* 3bodies list */ - Make_List( num_bonds, num_3body, TYP_THREE_BODY, lists[THREE_BODIES] ); + if ( first_run == TRUE ) + { + Make_List( num_bonds, num_bonds, num_3body, TYP_THREE_BODY, lists[THREE_BODIES] ); + } + else if ( lists[THREE_BODIES]->n_max < num_bonds + || lists[THREE_BODIES]->total_intrs < num_3body ) + { + Delete_List( TYP_THREE_BODY, lists[THREE_BODIES] ); + if ( lists[THREE_BODIES]->n_max < num_bonds ) + { + Make_List( num_bonds, num_bonds, num_3body, + TYP_THREE_BODY, lists[THREE_BODIES] ); + } + else + { + Make_List( num_bonds, lists[THREE_BODIES]->n_max, num_3body, + TYP_THREE_BODY, lists[THREE_BODIES] ); + } + } + else + { + lists[THREE_BODIES]->n = num_bonds; + } #if defined(DEBUG_FOCUS) fprintf( stderr, "estimated storage - num_3body: %d\n", num_3body ); @@ -885,12 +1002,12 @@ static void Init_Lists( reax_system *system, control_params *control, static void Init_Out_Controls( reax_system *system, control_params *control, - static_storage *workspace, output_controls *out_control ) + static_storage *workspace, output_controls *out_control, int output_enabled ) { #define TEMP_SIZE (1000) char temp[TEMP_SIZE]; - if ( out_control->write_steps > 0 ) + if ( output_enabled == TRUE && out_control->write_steps > 0 ) { strncpy( temp, control->sim_name, TEMP_SIZE - 5 ); temp[TEMP_SIZE - 5] = '\0'; @@ -903,7 +1020,7 @@ static void Init_Out_Controls( reax_system *system, control_params *control, out_control->trj = NULL; } - if ( out_control->log_update_freq > 0 ) + if ( output_enabled == TRUE && out_control->log_update_freq > 0 ) { strncpy( temp, control->sim_name, TEMP_SIZE - 5 ); temp[TEMP_SIZE - 5] = '\0'; @@ -940,8 +1057,8 @@ static void Init_Out_Controls( reax_system *system, control_params *control, out_control->log = NULL; } - if ( control->ensemble == sNPT || control->ensemble == iNPT - || control->ensemble == aNPT || control->compute_pressure == TRUE ) + if ( output_enabled == TRUE && (control->ensemble == sNPT || control->ensemble == iNPT + || control->ensemble == aNPT || control->compute_pressure == TRUE) ) { strncpy( temp, control->sim_name, TEMP_SIZE - 5 ); temp[TEMP_SIZE - 5] = '\0'; @@ -964,7 +1081,7 @@ static void Init_Out_Controls( reax_system *system, control_params *control, } /* Init molecular analysis file */ - if ( control->molec_anal ) + if ( output_enabled == TRUE && control->molec_anal ) { snprintf( temp, TEMP_SIZE, "%.*s.mol", TEMP_SIZE - 5, control->sim_name ); out_control->mol = sfopen( temp, "w" ); @@ -980,7 +1097,7 @@ static void Init_Out_Controls( reax_system *system, control_params *control, out_control->ign = NULL; } - if ( control->dipole_anal ) + if ( output_enabled == TRUE && control->dipole_anal ) { strncpy( temp, control->sim_name, TEMP_SIZE - 5 ); temp[TEMP_SIZE - 5] = '\0'; @@ -995,7 +1112,7 @@ static void Init_Out_Controls( reax_system *system, control_params *control, out_control->dpl = NULL; } - if ( control->diffusion_coef ) + if ( output_enabled == TRUE && control->diffusion_coef ) { strncpy( temp, control->sim_name, TEMP_SIZE - 6 ); temp[TEMP_SIZE - 6] = '\0'; @@ -1148,12 +1265,8 @@ static void Init_Out_Controls( reax_system *system, control_params *control, void Initialize( reax_system *system, control_params *control, simulation_data *data, static_storage *workspace, reax_list **lists, output_controls *out_control, evolve_function *Evolve, - const int output_enabled ) + int output_enabled, int first_run, int alloc ) { -#if defined(DEBUG) - real start, end; -#endif - #if defined(_OPENMP) #pragma omp parallel default(none) shared(control) { @@ -1166,18 +1279,15 @@ void Initialize( reax_system *system, control_params *control, Randomize( ); - Init_System( system, control, data ); + Init_System( system, control, data, first_run ); - Init_Simulation_Data( system, control, data, out_control, Evolve ); + Init_Simulation_Data( system, control, data, out_control, Evolve, alloc ); - Init_Workspace( system, control, workspace ); + Init_Workspace( system, control, workspace, alloc ); - Init_Lists( system, control, data, workspace, lists, out_control ); + Init_Lists( system, control, data, workspace, lists, out_control, first_run, alloc ); - if ( output_enabled == TRUE ) - { - Init_Out_Controls( system, control, workspace, out_control ); - } + Init_Out_Controls( system, control, workspace, out_control, output_enabled ); /* These are done in forces.c, only forces.c can see all those functions */ Init_Bonded_Force_Functions( control ); @@ -1188,27 +1298,13 @@ void Initialize( reax_system *system, control_params *control, if ( control->tabulate ) { -#if defined(DEBUG) - start = Get_Time( ); -#endif - Make_LR_Lookup_Table( system, control, workspace ); - -#if defined(DEBUG) - end = Get_Timing_Info( start ); - - fprintf( stderr, "[INFO] LR lookup table calculation time: %f\n", end ); -#endif } - -#if defined(DEBUG_FOCUS) - fprintf( stderr, "data structures have been initialized...\n" ); -#endif } static void Finalize_System( reax_system *system, control_params *control, - simulation_data *data ) + simulation_data *data, int reset ) { int i, j, k; reax_interaction *reax; @@ -1217,35 +1313,38 @@ static void Finalize_System( reax_system *system, control_params *control, Finalize_Grid( system ); - sfree( reax->gp.l, "Finalize_System::reax->gp.l" ); - - for ( i = 0; i < reax->num_atom_types; i++ ) + if ( reset == FALSE ) { - for ( j = 0; j < reax->num_atom_types; j++ ) + sfree( reax->gp.l, "Finalize_System::reax->gp.l" ); + + for ( i = 0; i < reax->num_atom_types; i++ ) { - for ( k = 0; k < reax->num_atom_types; k++ ) + for ( j = 0; j < reax->num_atom_types; j++ ) { - sfree( reax->fbp[i][j][k], "Finalize_System::reax->fbp[i][j][k]" ); + for ( k = 0; k < reax->num_atom_types; k++ ) + { + sfree( reax->fbp[i][j][k], "Finalize_System::reax->fbp[i][j][k]" ); + } + + sfree( reax->thbp[i][j], "Finalize_System::reax->thbp[i][j]" ); + sfree( reax->hbp[i][j], "Finalize_System::reax->hbp[i][j]" ); + sfree( reax->fbp[i][j], "Finalize_System::reax->fbp[i][j]" ); } - sfree( reax->thbp[i][j], "Finalize_System::reax->thbp[i][j]" ); - sfree( reax->hbp[i][j], "Finalize_System::reax->hbp[i][j]" ); - sfree( reax->fbp[i][j], "Finalize_System::reax->fbp[i][j]" ); + sfree( reax->tbp[i], "Finalize_System::reax->tbp[i]" ); + sfree( reax->thbp[i], "Finalize_System::reax->thbp[i]" ); + sfree( reax->hbp[i], "Finalize_System::reax->hbp[i]" ); + sfree( reax->fbp[i], "Finalize_System::reax->fbp[i]" ); } - sfree( reax->tbp[i], "Finalize_System::reax->tbp[i]" ); - sfree( reax->thbp[i], "Finalize_System::reax->thbp[i]" ); - sfree( reax->hbp[i], "Finalize_System::reax->hbp[i]" ); - sfree( reax->fbp[i], "Finalize_System::reax->fbp[i]" ); - } - - sfree( reax->sbp, "Finalize_System::reax->sbp" ); - sfree( reax->tbp, "Finalize_System::reax->tbp" ); - sfree( reax->thbp, "Finalize_System::reax->thbp" ); - sfree( reax->hbp, "Finalize_System::reax->hbp" ); - sfree( reax->fbp, "Finalize_System::reax->fbp" ); + sfree( reax->sbp, "Finalize_System::reax->sbp" ); + sfree( reax->tbp, "Finalize_System::reax->tbp" ); + sfree( reax->thbp, "Finalize_System::reax->thbp" ); + sfree( reax->hbp, "Finalize_System::reax->hbp" ); + sfree( reax->fbp, "Finalize_System::reax->fbp" ); - sfree( system->atoms, "Finalize_System::system->atoms" ); + sfree( system->atoms, "Finalize_System::system->atoms" ); + } } @@ -1256,14 +1355,14 @@ static void Finalize_Simulation_Data( reax_system *system, control_params *contr if ( control->ensemble == sNPT || control->ensemble == iNPT || control->ensemble == aNPT || control->compute_pressure == TRUE ) { - sfree( data->press_local, "Finalize_Workspace::workspace->press_local" ); + sfree( data->press_local, "Finalize_Simulation_Data::data->press_local" ); } #endif } static void Finalize_Workspace( reax_system *system, control_params *control, - static_storage *workspace ) + static_storage *workspace, int reset ) { int i; @@ -1285,9 +1384,9 @@ static void Finalize_Workspace( reax_system *system, control_params *control, sfree( workspace->CdDelta, "Finalize_Workspace::workspace->CdDelta" ); sfree( workspace->vlpex, "Finalize_Workspace::workspace->vlpex" ); - if ( control->geo_format == BGF + if ( reset == FALSE && (control->geo_format == BGF || control->geo_format == ASCII_RESTART - || control->geo_format == BINARY_RESTART ) + || control->geo_format == BINARY_RESTART) ) { sfree( workspace->map_serials, "Finalize_Workspace::workspace->map_serials" ); } @@ -1472,19 +1571,22 @@ static void Finalize_Workspace( reax_system *system, control_params *control, sfree( workspace->x_old, "Finalize_Workspace::workspace->x_old" ); } - sfree( workspace->orig_id, "Finalize_Workspace::workspace->orig_id" ); - - /* space for keeping restriction info, if any */ - if ( control->restrict_bonds ) + if ( reset == FALSE ) { - for ( i = 0; i < system->N; ++i ) + sfree( workspace->orig_id, "Finalize_Workspace::workspace->orig_id" ); + + /* space for keeping restriction info, if any */ + if ( control->restrict_bonds ) { - sfree( workspace->restricted_list[i], - "Finalize_Workspace::workspace->restricted_list[i]" ); - } + for ( i = 0; i < system->N; ++i ) + { + sfree( workspace->restricted_list[i], + "Finalize_Workspace::workspace->restricted_list[i]" ); + } - sfree( workspace->restricted, "Finalize_Workspace::workspace->restricted" ); - sfree( workspace->restricted_list, "Finalize_Workspace::workspace->restricted_list" ); + sfree( workspace->restricted, "Finalize_Workspace::workspace->restricted" ); + sfree( workspace->restricted_list, "Finalize_Workspace::workspace->restricted_list" ); + } } #if defined(TEST_FORCES) @@ -1600,7 +1702,7 @@ static void Finalize_Out_Controls( reax_system *system, control_params *control, */ void Finalize( reax_system *system, control_params *control, simulation_data *data, static_storage *workspace, reax_list **lists, - output_controls *out_control, const int output_enabled ) + output_controls *out_control, int output_enabled, int reset ) { if ( control->tabulate ) { @@ -1614,9 +1716,9 @@ void Finalize( reax_system *system, control_params *control, Finalize_Lists( control, lists ); - Finalize_Workspace( system, control, workspace ); + Finalize_Workspace( system, control, workspace, reset ); Finalize_Simulation_Data( system, control, data, out_control ); - Finalize_System( system, control, data ); + Finalize_System( system, control, data, reset ); } diff --git a/sPuReMD/src/init_md.h b/sPuReMD/src/init_md.h index 98d5cc90902422075a705c71de6508df5c8a36e2..26b3b0d5229f4111964c50af27b966661d1afcd8 100644 --- a/sPuReMD/src/init_md.h +++ b/sPuReMD/src/init_md.h @@ -27,10 +27,10 @@ void Initialize( reax_system*, control_params*, simulation_data*, static_storage*, reax_list**, output_controls*, evolve_function*, - const int ); + int, int, int ); void Finalize( reax_system*, control_params*, simulation_data*, - static_storage*, reax_list**, output_controls*, const int ); + static_storage*, reax_list**, output_controls*, int, int ); #endif diff --git a/sPuReMD/src/lin_alg.c b/sPuReMD/src/lin_alg.c index 9fc07f2d3efbf8e0b37c8ac996261df31a329bd1..44ddce77c8107bf7363809d72cf713eb15937901 100644 --- a/sPuReMD/src/lin_alg.c +++ b/sPuReMD/src/lin_alg.c @@ -57,7 +57,7 @@ static sparse_matrix * create_test_mat( void ) unsigned int i, n; sparse_matrix *H_test; - Allocate_Matrix( &H_test, 3, 6 ); + Allocate_Matrix( &H_test, 3, 3, 6 ); //3x3, SPD, store lower half i = 0; @@ -169,15 +169,15 @@ static void compute_full_sparse_matrix( const sparse_matrix * const A, if ( *A_full == NULL ) { - Allocate_Matrix( A_full, A->n, 2 * A->m - A->n ); + Allocate_Matrix( A_full, A->n, A->n_max, 2 * A->m - A->n ); } else if ( (*A_full)->m < 2 * A->m - A->n ) { Deallocate_Matrix( *A_full ); - Allocate_Matrix( A_full, A->n, 2 * A->m - A->n ); + Allocate_Matrix( A_full, A->n, A->n_max, 2 * A->m - A->n ); } - Allocate_Matrix( &A_t, A->n, A->m ); + Allocate_Matrix( &A_t, A->n, A->n_max, A->m ); /* Set up the sparse matrix data structure for A. */ Transpose( A, A_t ); @@ -233,12 +233,12 @@ void setup_sparse_approx_inverse( const sparse_matrix * const A, sparse_matrix * if ( *A_spar_patt == NULL ) { - Allocate_Matrix( A_spar_patt, A->n, A->m ); + Allocate_Matrix( A_spar_patt, A->n, A->n_max, A->m ); } else if ( ((*A_spar_patt)->m) < (A->m) ) { Deallocate_Matrix( *A_spar_patt ); - Allocate_Matrix( A_spar_patt, A->n, A->m ); + Allocate_Matrix( A_spar_patt, A->n, A->n_max, A->m ); } list = smalloc( sizeof(real) * A->start[A->n], @@ -352,7 +352,8 @@ void setup_sparse_approx_inverse( const sparse_matrix * const A, sparse_matrix * { /* A_app_inv has the same sparsity pattern * as A_spar_patt_full (omit non-zero values) */ - Allocate_Matrix( A_app_inv, (*A_spar_patt_full)->n, (*A_spar_patt_full)->m ); + Allocate_Matrix( A_app_inv, (*A_spar_patt_full)->n, (*A_spar_patt_full)->n_max, + (*A_spar_patt_full)->m ); } else if ( (*A_app_inv)->m < A->m ) { @@ -360,7 +361,8 @@ void setup_sparse_approx_inverse( const sparse_matrix * const A, sparse_matrix * /* A_app_inv has the same sparsity pattern * as A_spar_patt_full (omit non-zero values) */ - Allocate_Matrix( A_app_inv, (*A_spar_patt_full)->n, (*A_spar_patt_full)->m ); + Allocate_Matrix( A_app_inv, (*A_spar_patt_full)->n, (*A_spar_patt_full)->n_max, + (*A_spar_patt_full)->m ); } sfree( list, "setup_sparse_approx_inverse::list" ); @@ -1130,8 +1132,8 @@ real FG_ICHOLT( const sparse_matrix * const A, const real * droptol, start = Get_Time( ); - Allocate_Matrix( &DAD, A->n, A->m ); - Allocate_Matrix( &U_T_temp, A->n, A->m ); + Allocate_Matrix( &DAD, A->n, A->n_max, A->m ); + Allocate_Matrix( &U_T_temp, A->n, A->n_max, A->m ); D = smalloc( sizeof(real) * A->n, "FG_ICHOLT::D" ); D_inv = smalloc( sizeof(real) * A->n, "FG_ICHOLT::D_inv" ); @@ -1338,9 +1340,9 @@ real FG_ILUT( const sparse_matrix * const A, const real * droptol, start = Get_Time( ); - Allocate_Matrix( &DAD, A->n, A->m ); - Allocate_Matrix( &L_temp, A->n, A->m ); - Allocate_Matrix( &U_T_temp, A->n, A->m ); + Allocate_Matrix( &DAD, A->n, A->n_max, A->m ); + Allocate_Matrix( &L_temp, A->n, A->n_max, A->m ); + Allocate_Matrix( &U_T_temp, A->n, A->n_max, A->m ); D = smalloc( sizeof(real) * A->n, "FG_ILUT::D" ); D_inv = smalloc( sizeof(real) * A->n, "FG_ILUT::D_inv" ); @@ -1980,7 +1982,7 @@ void Transpose_I( sparse_matrix * const A ) { sparse_matrix * A_t; - Allocate_Matrix( &A_t, A->n, A->m ); + Allocate_Matrix( &A_t, A->n, A->n_max, A->m ); Transpose( A, A_t ); @@ -2487,7 +2489,7 @@ static void permute_matrix( const static_storage * const workspace, int i, pj, nr, nc; sparse_matrix *LUtemp; - Allocate_Matrix( &LUtemp, LU->n, LU->m ); + Allocate_Matrix( &LUtemp, LU->n, LU->n_max, LU->m ); for ( i = 0; i < LU->n + 1; ++i ) workspace->color_top[i] = 0; @@ -2623,12 +2625,12 @@ void setup_graph_coloring( const control_params * const control, { if ( *H_p == NULL ) { - Allocate_Matrix( H_p, H->n, H->m ); + Allocate_Matrix( H_p, H->n, H->n_max, H->m ); } else if ( (*H_p)->m < H->m ) { Deallocate_Matrix( *H_p ); - Allocate_Matrix( H_p, H->n, H->m ); + Allocate_Matrix( H_p, H->n, H->n_max, H->m ); } compute_full_sparse_matrix( H, H_full ); diff --git a/sPuReMD/src/list.c b/sPuReMD/src/list.c index ad7bbc626fa343eadda8f481274f7d9fde0b0aed..f5414e93a3424e97364dda0382e201eb82ad1a72 100644 --- a/sPuReMD/src/list.c +++ b/sPuReMD/src/list.c @@ -24,17 +24,20 @@ #include "tool_box.h" -void Make_List( int n, int total_intrs, int type, reax_list* l ) +void Make_List( int n, int n_max, int total_intrs, int type, reax_list* l ) { assert( n > 0 ); + assert( n_max > 0 ); + assert( n_max >= n ); assert( total_intrs > 0 ); assert( l != NULL ); l->n = n; + l->n_max = n_max; l->total_intrs = total_intrs; - l->index = smalloc( n * sizeof(int), "Make_List::l->index" ); - l->end_index = smalloc( n * sizeof(int), "Make_List::l->end_index" ); + l->index = smalloc( n_max * sizeof(int), "Make_List::l->index" ); + l->end_index = smalloc( n_max * sizeof(int), "Make_List::l->end_index" ); switch ( type ) { diff --git a/sPuReMD/src/list.h b/sPuReMD/src/list.h index c83d8546b1386100bdaa69599757253b862cb2f1..3a0bcdcb39d1f57bd76eaaab3de8149a1f8935e1 100644 --- a/sPuReMD/src/list.h +++ b/sPuReMD/src/list.h @@ -25,7 +25,7 @@ #include "reax_types.h" -void Make_List( int, int, int, reax_list* ); +void Make_List( int, int, int, int, reax_list* ); void Delete_List( int, reax_list* ); diff --git a/sPuReMD/src/reax_types.h b/sPuReMD/src/reax_types.h index 734ad9b5eb8cbcad32f5c03b331868d156a6b199..f1fac619f57aea003770c24365ea9b3749f42e04 100644 --- a/sPuReMD/src/reax_types.h +++ b/sPuReMD/src/reax_types.h @@ -786,14 +786,14 @@ struct grid /* max. num. of neighbors for a grid cell; * used for memory allocation purposes */ int max_nbrs; - /**/ - int total; /* lengths of each dimesion of a grid cell */ real cell_size; /**/ ivec spread; - /* num. of cells along each dimension for entire grid */ + /* num. of cells along each dimension for entire grid for this simulation */ ivec ncell; + /* max. num. of cells along each dimension for entire grid across all simulations */ + ivec ncell_max; /* lengths of each dimesion of a grid cell */ rvec len; /* multiplicative inverse of length of each dimesion of a grid cell */ @@ -820,10 +820,14 @@ struct grid struct reax_system { - /* number of local (non-periodic image) atoms */ + /* number of local (non-periodic image) atoms for the current simulation */ int N; + /* max. number of local (non-periodic image) atoms across all simulations */ + int N_max; /* dimension of the N x N sparse charge method matrix H */ int N_cm; + /* max. dimension of the N x N sparse charge method matrix H across all simulations */ + int N_cm_max; /* atom info */ reax_atom *atoms; /* atomic interaction parameters */ @@ -1122,6 +1126,8 @@ struct reax_timing struct simulation_data { + /* integer ID uniquely identifying the simulation */ + int sim_id; /* current simulation step number (0-based) */ int step; /* last simulation step number for restarted runs (0-based) */ @@ -1349,8 +1355,10 @@ struct bond_data */ struct sparse_matrix { - /* number of rows */ + /* active number of rows for this simulation */ unsigned int n; + /* max. number of rows across all simulations */ + unsigned int n_max; /* number of nonzeros (NNZ) ALLOCATED */ unsigned int m; /* row pointer (last element contains ACTUAL NNZ) */ @@ -1530,8 +1538,12 @@ struct static_storage /* permutation for ILUTP */ unsigned int *perm_ilutp; + /* num. hydrogen atoms for this simulation */ int num_H; - int *hbond_index; // for hydrogen bonds + /* max. num. hydrogen atoms across all simulations */ + int num_H_max; + /* for hydrogen bonds */ + int *hbond_index; rvec *v_const; rvec *f_old; @@ -1586,15 +1598,17 @@ struct static_storage /* interaction lists */ struct reax_list { - /* num. entries in list */ + /* num. active entries in list for this simulation */ int n; - /* sum of max. interactions per atom */ + /* max. num. entries in list across all simulations */ + int n_max; + /* total interactions across all entries which can be stored in the list */ int total_intrs; /* starting position of atom's interactions */ int *index; /* ending position of atom's interactions */ int *end_index; - /* max. num. of interactions per atom */ + /* max. num. of interactions per list entry */ int *max_intrs; /* interaction list (polymorphic via union dereference) */ // union @@ -1701,20 +1715,24 @@ struct output_controls /* Handle for working with an instance of the sPuReMD library */ struct spuremd_handle { - /* System info. struct pointer */ + /* System info. */ reax_system *system; - /* Control parameters struct pointer */ + /* Control parameters */ control_params *control; - /* Atomic simulation data struct pointer */ + /* Atomic simulation data */ simulation_data *data; - /* Internal workspace struct pointer */ + /* Internal workspace */ static_storage *workspace; - /* Reax interaction list struct pointer */ + /* Reax interaction list */ reax_list **lists; - /* Output controls struct pointer */ + /* Output controls */ output_controls *out_control; + /* TRUE for first simulation, FALSE otherwise */ + int first_run; /* TRUE if file I/O for simulation output enabled, FALSE otherwise */ int output_enabled; + /* TRUE if reallocation is required due to num. atoms increasing, FALSE otherwise */ + int realloc; /* Callback for getting simulation state at the end of each time step */ callback_function callback; }; diff --git a/sPuReMD/src/restart.c b/sPuReMD/src/restart.c index 0cdbcd4dbb184efcef6c4e80883c2c15986c2c50..32b3a62244b6cbdd1e62c30c0134edc21c393cc3 100644 --- a/sPuReMD/src/restart.c +++ b/sPuReMD/src/restart.c @@ -73,7 +73,7 @@ void Write_Binary_Restart( reax_system *system, control_params *control, void Read_Binary_Restart( const char * const fname, reax_system *system, control_params *control, simulation_data *data, - static_storage *workspace ) + static_storage *workspace, int first_run ) { int i; FILE *fres; @@ -87,7 +87,6 @@ void Read_Binary_Restart( const char * const fname, reax_system *system, fread( &res_header, sizeof(restart_header), 1, fres ); data->prev_steps = res_header.step; - system->N = res_header.N; data->therm.T = res_header.T; data->therm.xi = res_header.xi; data->therm.v_xi = res_header.v_xi; @@ -109,10 +108,17 @@ void Read_Binary_Restart( const char * const fname, reax_system *system, system->box.box[2][0], system->box.box[2][1], system->box.box[2][2] ); #endif - PreAllocate_Space( system, control, workspace ); + if ( first_run == TRUE || res_header.N > system->N ) + { + PreAllocate_Space( system, control, workspace, res_header.N, first_run ); + } + system->N = res_header.N; - workspace->map_serials = scalloc( MAX_ATOM_ID, sizeof(int), - "Read_Binary_Restart::workspace->map_serials" ); + if ( first_run == TRUE ) + { + workspace->map_serials = scalloc( MAX_ATOM_ID, sizeof(int), + "Read_Binary_Restart::workspace->map_serials" ); + } for ( i = 0; i < MAX_ATOM_ID; ++i ) { @@ -185,9 +191,9 @@ void Write_ASCII_Restart( reax_system *system, control_params *control, void Read_ASCII_Restart( const char * const fname, reax_system *system, control_params *control, simulation_data *data, - static_storage *workspace ) + static_storage *workspace, int first_run ) { - int i; + int i, n; FILE *fres; reax_atom *p_atom; @@ -195,7 +201,7 @@ void Read_ASCII_Restart( const char * const fname, reax_system *system, /* parse header of restart file */ fscanf( fres, READ_RESTART_HEADER, - &data->prev_steps, &system->N, &data->therm.T, &data->therm.xi, + &data->prev_steps, &n, &data->therm.T, &data->therm.xi, &data->therm.v_xi, &data->therm.v_xi_old, &data->therm.G_xi, &system->box.box[0][0], &system->box.box[0][1], &system->box.box[0][2], &system->box.box[1][0], &system->box.box[1][1], &system->box.box[1][2], @@ -216,10 +222,17 @@ void Read_ASCII_Restart( const char * const fname, reax_system *system, system->box.box[2][0], system->box.box[2][1], system->box.box[2][2] ); #endif - PreAllocate_Space( system, control, workspace ); + if ( first_run == TRUE || n > system->N ) + { + PreAllocate_Space( system, control, workspace, n, first_run ); + } + system->N = n; - workspace->map_serials = scalloc( MAX_ATOM_ID, sizeof(int), - "Read_ASCII_Restart::workspace->map_serials" ); + if ( first_run == TRUE ) + { + workspace->map_serials = scalloc( MAX_ATOM_ID, sizeof(int), + "Read_ASCII_Restart::workspace->map_serials" ); + } for ( i = 0; i < MAX_ATOM_ID; ++i ) { diff --git a/sPuReMD/src/restart.h b/sPuReMD/src/restart.h index cfa36c5afaa05bebdddf4ba72cd8f9f354cf3361..41e221eaafc0c99b558b0116344cb83b45cecef8 100644 --- a/sPuReMD/src/restart.h +++ b/sPuReMD/src/restart.h @@ -53,12 +53,12 @@ typedef struct #define READ_RESTART_HEADER " %d %d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf" #define READ_RESTART_LINE " %d %d %s %lf %lf %lf %lf %lf %lf" -void Write_Restart( reax_system*, control_params*, - simulation_data*, static_storage*, output_controls* ); +void Write_Restart( reax_system *, control_params *, + simulation_data *, static_storage *, output_controls * ); -void Read_Binary_Restart( const char * const, reax_system*, control_params*, - simulation_data*, static_storage* ); -void Read_ASCII_Restart( const char * const, reax_system*, control_params*, - simulation_data*, static_storage* ); +void Read_Binary_Restart( const char * const, reax_system *, control_params *, + simulation_data *, static_storage *, int ); +void Read_ASCII_Restart( const char * const, reax_system *, control_params *, + simulation_data *, static_storage *, int ); #endif diff --git a/sPuReMD/src/spuremd.c b/sPuReMD/src/spuremd.c index d009d160e52e11de7f6d654ed0faf78d8eef53a6..453b0263837bd685e61815365bcda06d445f2e7a 100644 --- a/sPuReMD/src/spuremd.c +++ b/sPuReMD/src/spuremd.c @@ -39,6 +39,9 @@ #include "vector.h" +/* Handles additional entire geometry calculations after + * perturbing atom positions during a simulation step + */ static void Post_Evolve( reax_system * const system, control_params * const control, simulation_data * const data, static_storage * const workspace, reax_list ** const lists, output_controls * const out_control ) @@ -51,7 +54,7 @@ static void Post_Evolve( reax_system * const system, control_params * const cont && data->step % control->remove_CoM_vel == 0 ) { /* compute velocity of the center of mass */ - Compute_Center_of_Mass( system, data, out_control->prs ); + Compute_Center_of_Mass( system, data ); for ( i = 0; i < system->N; i++ ) { @@ -83,44 +86,47 @@ static void Post_Evolve( reax_system * const system, control_params * const cont } -static void Read_System( const char * const geo_file, - const char * const ffield_file, - const char * const control_file, - reax_system * const system, - control_params * const control, - simulation_data * const data, - static_storage * const workspace, - output_controls * const out_control ) +/* Parse input files + * + * geo_file: file containing geometry info of the structure to simulate + * ffield_file: file containing force field parameters + * control_file: file containing simulation parameters + */ +static void Read_Input_Files( const char * const geo_file, + const char * const ffield_file, const char * const control_file, + reax_system * const system, control_params * const control, + simulation_data * const data, static_storage * const workspace, + output_controls * const out_control, int first_run ) { FILE *ffield, *ctrl; ffield = sfopen( ffield_file, "r" ); ctrl = sfopen( control_file, "r" ); - Read_Force_Field( ffield, &system->reax_param ); + Read_Force_Field( ffield, &system->reax_param, first_run ); Read_Control_File( ctrl, system, control, out_control ); if ( control->geo_format == CUSTOM ) { - Read_Geo( geo_file, system, control, data, workspace ); + Read_Geo( geo_file, system, control, data, workspace, first_run ); } else if ( control->geo_format == PDB ) { - Read_PDB( geo_file, system, control, data, workspace ); + Read_PDB( geo_file, system, control, data, workspace, first_run ); } else if ( control->geo_format == BGF ) { - Read_BGF( geo_file, system, control, data, workspace ); + Read_BGF( geo_file, system, control, data, workspace, first_run ); } else if ( control->geo_format == ASCII_RESTART ) { - Read_ASCII_Restart( geo_file, system, control, data, workspace ); + Read_ASCII_Restart( geo_file, system, control, data, workspace, first_run ); control->restart = TRUE; } else if ( control->geo_format == BINARY_RESTART ) { - Read_Binary_Restart( geo_file, system, control, data, workspace ); + Read_Binary_Restart( geo_file, system, control, data, workspace, first_run ); control->restart = TRUE; } else @@ -129,16 +135,22 @@ static void Read_System( const char * const geo_file, exit( INVALID_GEO ); } - sfclose( ffield, "Read_System::ffield" ); - sfclose( ctrl, "Read_System::ctrl" ); + sfclose( ffield, "Read_Input_Files::ffield" ); + sfclose( ctrl, "Read_Input_Files::ctrl" ); #if defined(DEBUG_FOCUS) - fprintf( stderr, "input files have been read...\n" ); Print_Box( &system->box, stderr ); #endif } +/* Allocate top-level data structures and parse input files + * for the first simulation + * + * geo_file: file containing geometry info of the structure to simulate + * ffield_file: file containing force field parameters + * control_file: file containing simulation parameters + */ void* setup( const char * const geo_file, const char * const ffield_file, const char * const control_file ) { @@ -169,19 +181,28 @@ void* setup( const char * const geo_file, const char * const ffield_file, spmd_handle->out_control = smalloc( sizeof(output_controls), "Setup::spmd_handle->out_control" ); + spmd_handle->first_run = TRUE; spmd_handle->output_enabled = TRUE; + spmd_handle->realloc = TRUE; spmd_handle->callback = NULL; + spmd_handle->data->sim_id = 0; - /* parse geometry file */ - Read_System( geo_file, ffield_file, control_file, + Read_Input_Files( geo_file, ffield_file, control_file, spmd_handle->system, spmd_handle->control, spmd_handle->data, spmd_handle->workspace, - spmd_handle->out_control ); + spmd_handle->out_control, spmd_handle->first_run ); + + spmd_handle->system->N_max = (int) CEIL( SAFE_ZONE * spmd_handle->system->N ); return (void*) spmd_handle; } +/* Setup callback function to be run after each simulation step + * + * handle: pointer to wrapper struct with top-level data structures + * callback: function pointer to attach for callback + */ int setup_callback( const void * const handle, const callback_function callback ) { int ret; @@ -201,6 +222,10 @@ int setup_callback( const void * const handle, const callback_function callback } +/* Run the simulation according to the prescribed parameters + * + * handle: pointer to wrapper struct with top-level data structures + */ int simulate( const void * const handle ) { int steps, ret; @@ -216,7 +241,10 @@ int simulate( const void * const handle ) Initialize( spmd_handle->system, spmd_handle->control, spmd_handle->data, spmd_handle->workspace, spmd_handle->lists, spmd_handle->out_control, &Evolve, - spmd_handle->output_enabled ); + spmd_handle->output_enabled, + spmd_handle->first_run, spmd_handle->realloc ); + + spmd_handle->realloc = FALSE; /* compute f_0 */ //if( control.restart == FALSE ) { @@ -248,7 +276,10 @@ int simulate( const void * const handle ) { Compute_Total_Energy( spmd_handle->data ); } + } + if ( spmd_handle->output_enabled == TRUE ) + { Output_Results( spmd_handle->system, spmd_handle->control, spmd_handle->data, spmd_handle->workspace, spmd_handle->lists, spmd_handle->out_control ); } @@ -338,6 +369,10 @@ int simulate( const void * const handle ) } +/* Deallocate all data structures post-simulation + * + * handle: pointer to wrapper struct with top-level data structures + */ int cleanup( const void * const handle ) { int i, ret; @@ -351,7 +386,7 @@ int cleanup( const void * const handle ) Finalize( spmd_handle->system, spmd_handle->control, spmd_handle->data, spmd_handle->workspace, spmd_handle->lists, spmd_handle->out_control, - spmd_handle->output_enabled ); + spmd_handle->output_enabled, FALSE ); sfree( spmd_handle->out_control, "cleanup::spmd_handle->out_control" ); for ( i = 0; i < LIST_N; ++i ) @@ -373,6 +408,59 @@ int cleanup( const void * const handle ) } +/* Reset for the next simulation by parsing input files and triggering + * reallocation if more space is needed + * + * handle: pointer to wrapper struct with top-level data structures + * geo_file: file containing geometry info of the structure to simulate + * ffield_file: file containing force field parameters + * control_file: file containing simulation parameters + */ +int reset( const void * const handle, const char * const geo_file, + const char * const ffield_file, const char * const control_file ) +{ + int ret; + spuremd_handle *spmd_handle; + + ret = SPUREMD_FAILURE; + + if ( handle != NULL ) + { + spmd_handle = (spuremd_handle*) handle; + + spmd_handle->first_run = FALSE; + spmd_handle->realloc = FALSE; + spmd_handle->data->sim_id++; + + Read_Input_Files( geo_file, ffield_file, control_file, + spmd_handle->system, spmd_handle->control, + spmd_handle->data, spmd_handle->workspace, + spmd_handle->out_control, spmd_handle->first_run ); + + if ( spmd_handle->system->N > spmd_handle->system->N_max ) + { + /* deallocate everything which needs more space + * (i.e., structures whose space is a function of the number of atoms), + * except for data structures allocated while parsing input files */ + Finalize( spmd_handle->system, spmd_handle->control, spmd_handle->data, + spmd_handle->workspace, spmd_handle->lists, spmd_handle->out_control, + spmd_handle->output_enabled, TRUE ); + + spmd_handle->system->N_max = (int) CEIL( SAFE_ZONE * spmd_handle->system->N ); + spmd_handle->realloc = TRUE; + } + + ret = SPUREMD_SUCCESS; + } + + return ret; +} + + +/* Getter for atom info + * + * handle: pointer to wrapper struct with top-level data structures + */ reax_atom* get_atoms( const void * const handle ) { spuremd_handle *spmd_handle; @@ -390,6 +478,11 @@ reax_atom* get_atoms( const void * const handle ) } +/* Setter for writing output to files + * + * handle: pointer to wrapper struct with top-level data structures + * enabled: TRUE enables writing output to files, FALSE otherwise + */ int set_output_enabled( const void * const handle, const int enabled ) { int ret; diff --git a/sPuReMD/src/spuremd.h b/sPuReMD/src/spuremd.h index 64e263d1475e2d01ab571432f58db630cff974aa..980d3448981a8a9ed6c05e23391a46c84f046fc8 100644 --- a/sPuReMD/src/spuremd.h +++ b/sPuReMD/src/spuremd.h @@ -42,6 +42,9 @@ int simulate( const void * const ); int cleanup( const void * const ); +int reset( const void * const, const char * const, + const char * const, const char * const ); + reax_atom* get_atoms( const void * const ); int set_output_enabled( const void * const, const int ); diff --git a/sPuReMD/src/system_props.c b/sPuReMD/src/system_props.c index 5a9acd17641abc02825d6c9c0874cb3a3eeb0960..05f820003cea38039d2375b91a4e220e04c1ae4a 100644 --- a/sPuReMD/src/system_props.c +++ b/sPuReMD/src/system_props.c @@ -74,8 +74,7 @@ void Compute_Total_Mass( reax_system *system, simulation_data *data ) } -void Compute_Center_of_Mass( reax_system *system, simulation_data *data, - FILE *fout ) +void Compute_Center_of_Mass( reax_system *system, simulation_data *data ) { int i; real m, xx, xy, xz, yy, yz, zz, det; diff --git a/sPuReMD/src/system_props.h b/sPuReMD/src/system_props.h index 3b8d6a98f25188dd5a1dd604a2a90e15a5622880..26e1594b8cce64b7ee85db5cc3dee5c40f3442e6 100644 --- a/sPuReMD/src/system_props.h +++ b/sPuReMD/src/system_props.h @@ -29,7 +29,7 @@ void Temperature_Control( control_params*, simulation_data*, output_controls* ); void Compute_Total_Mass( reax_system*, simulation_data* ); -void Compute_Center_of_Mass( reax_system*, simulation_data*, FILE* ); +void Compute_Center_of_Mass( reax_system*, simulation_data* ); void Compute_Kinetic_Energy( reax_system*, simulation_data* );