From a5f1919310d033686aeb7fe04031dff2d66ebda7 Mon Sep 17 00:00:00 2001 From: "Kurt A. O'Hearn" <ohearnku@cse.msu.edu> Date: Thu, 28 Jan 2016 21:40:39 -0500 Subject: [PATCH] Autoformat. --- puremd_rc_1003/sPuReMD/GMRES.c | 1611 ++++++------ puremd_rc_1003/sPuReMD/GMRES.h | 42 +- puremd_rc_1003/sPuReMD/QEq.c | 616 ++--- puremd_rc_1003/sPuReMD/QEq.h | 14 +- puremd_rc_1003/sPuReMD/allocate.c | 412 +-- puremd_rc_1003/sPuReMD/allocate.h | 10 +- puremd_rc_1003/sPuReMD/analyze.c | 1611 ++++++------ puremd_rc_1003/sPuReMD/analyze.h | 22 +- puremd_rc_1003/sPuReMD/bond_orders.c | 1872 ++++++------- puremd_rc_1003/sPuReMD/bond_orders.h | 33 +- puremd_rc_1003/sPuReMD/box.c | 899 +++---- puremd_rc_1003/sPuReMD/box.h | 34 +- puremd_rc_1003/sPuReMD/forces.c | 1592 ++++++------ puremd_rc_1003/sPuReMD/forces.h | 18 +- .../sPuReMD/four_body_interactions.c | 1252 ++++----- .../sPuReMD/four_body_interactions.h | 12 +- puremd_rc_1003/sPuReMD/grid.c | 867 ++++--- puremd_rc_1003/sPuReMD/grid.h | 10 +- puremd_rc_1003/sPuReMD/init_md.c | 1130 ++++---- puremd_rc_1003/sPuReMD/init_md.h | 12 +- puremd_rc_1003/sPuReMD/integrate.c | 1201 ++++----- puremd_rc_1003/sPuReMD/integrate.h | 62 +- puremd_rc_1003/sPuReMD/list.c | 184 +- puremd_rc_1003/sPuReMD/list.h | 16 +- puremd_rc_1003/sPuReMD/lookup.c | 701 ++--- puremd_rc_1003/sPuReMD/lookup.h | 10 +- puremd_rc_1003/sPuReMD/mytypes.h | 1017 ++++---- puremd_rc_1003/sPuReMD/neighbors.c | 1094 ++++---- puremd_rc_1003/sPuReMD/neighbors.h | 16 +- puremd_rc_1003/sPuReMD/param.c | 2306 +++++++++-------- puremd_rc_1003/sPuReMD/param.h | 14 +- puremd_rc_1003/sPuReMD/pdb_tools.c | 1054 ++++---- puremd_rc_1003/sPuReMD/pdb_tools.h | 34 +- puremd_rc_1003/sPuReMD/print_utils.c | 1395 +++++----- puremd_rc_1003/sPuReMD/print_utils.h | 66 +- puremd_rc_1003/sPuReMD/random.c | 30 +- puremd_rc_1003/sPuReMD/random.h | 10 +- puremd_rc_1003/sPuReMD/reset_utils.c | 176 +- puremd_rc_1003/sPuReMD/reset_utils.h | 18 +- puremd_rc_1003/sPuReMD/restart.c | 370 +-- puremd_rc_1003/sPuReMD/restart.h | 44 +- .../sPuReMD/single_body_interactions.c | 521 ++-- .../sPuReMD/single_body_interactions.h | 17 +- puremd_rc_1003/sPuReMD/system_props.c | 530 ++-- puremd_rc_1003/sPuReMD/system_props.h | 10 +- puremd_rc_1003/sPuReMD/testmd.c | 302 +-- .../sPuReMD/three_body_interactions.c | 1463 ++++++----- .../sPuReMD/three_body_interactions.h | 18 +- puremd_rc_1003/sPuReMD/traj.c | 832 +++--- puremd_rc_1003/sPuReMD/traj.h | 81 +- .../sPuReMD/two_body_interactions.c | 1005 +++---- .../sPuReMD/two_body_interactions.h | 18 +- puremd_rc_1003/sPuReMD/vector.c | 478 ++-- puremd_rc_1003/sPuReMD/vector.h | 10 +- 54 files changed, 13927 insertions(+), 13245 deletions(-) diff --git a/puremd_rc_1003/sPuReMD/GMRES.c b/puremd_rc_1003/sPuReMD/GMRES.c index 8488ac69..2d8e1ab7 100644 --- a/puremd_rc_1003/sPuReMD/GMRES.c +++ b/puremd_rc_1003/sPuReMD/GMRES.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -31,33 +31,33 @@ * x: vector * b: vector (result) */ static void Sparse_MatVec( const sparse_matrix * const A, - const real * const x, real * const b ) + const real * const x, real * const b ) { - int i, j, k, n, si, ei; - real H; - - n = A->n; - for( i = 0; i < n; ++i ) - { - b[i] = 0; - } - - for( i = 0; i < n; ++i ) - { - si = A->start[i]; - ei = A->start[i+1]-1; - - for( k = si; k < ei; ++k ) + int i, j, k, n, si, ei; + real H; + + n = A->n; + for ( i = 0; i < n; ++i ) { - j = A->entries[k].j; - H = A->entries[k].val; - b[j] += H * x[i]; - b[i] += H * x[j]; + b[i] = 0; } - // the diagonal entry is the last one in - b[i] += A->entries[A->start[i+1]-1].val * x[i]; - } + for ( i = 0; i < n; ++i ) + { + si = A->start[i]; + ei = A->start[i + 1] - 1; + + for ( k = si; k < ei; ++k ) + { + j = A->entries[k].j; + H = A->entries[k].val; + b[j] += H * x[i]; + b[i] += H * x[j]; + } + + // the diagonal entry is the last one in + b[i] += A->entries[A->start[i + 1] - 1].val * x[i]; + } } @@ -68,82 +68,82 @@ static void Sparse_MatVec( const sparse_matrix * const A, * b: vector (result) * tri: triangularity of A (lower/upper) */ static void Sparse_MatVec2( const sparse_matrix * const A, - const TRIANGULARITY tri, const real * const x, real * const b) + const TRIANGULARITY tri, const real * const x, real * const b) { - int i, k, n, si = 0, ei = 0; + int i, k, n, si = 0, ei = 0; - n = A->n; - for( i = 0; i < n; ++i ) - { - b[i] = 0; - } - - for( i = 0; i < n; ++i ) - { - if(tri == LOWER) + n = A->n; + for ( i = 0; i < n; ++i ) { - si = A->start[i]; - ei = A->start[i+1]-1; + b[i] = 0; } - else if(tri == UPPER) - { - si = A->start[i]+1; - ei = A->start[i+1]; - } - - for( k = si; k < ei; ++k ) + for ( i = 0; i < n; ++i ) { - b[A->entries[k].j] += A->entries[k].j * x[i]; - b[i] += A->entries[k].j * x[A->entries[k].j]; + if (tri == LOWER) + { + si = A->start[i]; + ei = A->start[i + 1] - 1; + } + else if (tri == UPPER) + { + + si = A->start[i] + 1; + ei = A->start[i + 1]; + } + + for ( k = si; k < ei; ++k ) + { + b[A->entries[k].j] += A->entries[k].j * x[i]; + b[i] += A->entries[k].j * x[A->entries[k].j]; + } } - } } /* solve sparse lower triangular linear system using forward substitution */ void Forward_Subs( sparse_matrix *L, real *b, real *y ) { - int i, pj, j, si, ei; - real val; - - for( i = 0; i < L->n; ++i ) - { - y[i] = b[i]; - si = L->start[i]; - ei = L->start[i+1]; - for( pj = si; pj < ei-1; ++pj ) + int i, pj, j, si, ei; + real val; + + for ( i = 0; i < L->n; ++i ) { - // TODO: remove assignments? compiler optimizes away? - j = L->entries[pj].j; - val = L->entries[pj].val; - y[i] -= val * y[j]; + y[i] = b[i]; + si = L->start[i]; + ei = L->start[i + 1]; + for ( pj = si; pj < ei - 1; ++pj ) + { + // TODO: remove assignments? compiler optimizes away? + j = L->entries[pj].j; + val = L->entries[pj].val; + y[i] -= val * y[j]; + } + y[i] /= L->entries[pj].val; } - y[i] /= L->entries[pj].val; - } } /* solve sparse upper triangular linear system using backward substitution */ void Backward_Subs( sparse_matrix *U, real *y, real *x ) { - int i, pj, j, si, ei; - real val; - - for( i = U->n-1; i >= 0; --i ) - { - x[i] = y[i]; - si = U->start[i]; - ei = U->start[i+1]; - for( pj = si+1; pj < ei; ++pj ) + int i, pj, j, si, ei; + real val; + + for ( i = U->n - 1; i >= 0; --i ) { - // TODO: remove assignments? compiler optimizes away? - j = U->entries[pj].j; - val = U->entries[pj].val; - x[i] -= val * x[j]; + x[i] = y[i]; + si = U->start[i]; + ei = U->start[i + 1]; + for ( pj = si + 1; pj < ei; ++pj ) + { + // TODO: remove assignments? compiler optimizes away? + j = U->entries[pj].j; + val = U->entries[pj].val; + x[i] -= val * x[j]; + } + x[i] /= U->entries[si].val; } - x[i] /= U->entries[si].val; - } } @@ -159,767 +159,800 @@ void Backward_Subs( sparse_matrix *U, real *y, real *x ) * Note: Newmann series arises from series expansion of the inverse of * the coefficient matrix in the triangular system. */ static void Jacobi_Iter( const sparse_matrix * const G, const TRIANGULARITY tri, - const sparse_matrix * const Dinv, const real * const b, - real * const x, const unsigned int maxiter ) + const sparse_matrix * const Dinv, const real * const b, + real * const x, const unsigned int maxiter ) { - unsigned int iter = 0; - real *Dinv_b; - - if( (Dinv_b = (real*) malloc(sizeof(real)*(Dinv->n))) == NULL ) - { - fprintf( stderr, "not enough memory for Jacobi iteration matrices. terminating.\n" ); - exit(INSUFFICIENT_SPACE); - } - - /* precompute and cache, as invariant in loop below */ - Sparse_MatVec( (sparse_matrix*)Dinv, (real*)b, Dinv_b ); - - do - { - // x_{k+1} = G*x_{k} + Dinv*b; - Sparse_MatVec2( (sparse_matrix*)G, tri, x, x ); - Vector_Add2( x, Dinv_b, Dinv->n ); - ++iter; - } while( iter < maxiter ); - - free(Dinv_b); + unsigned int iter = 0; + real *Dinv_b; + + if ( (Dinv_b = (real*) malloc(sizeof(real) * (Dinv->n))) == NULL ) + { + fprintf( stderr, "not enough memory for Jacobi iteration matrices. terminating.\n" ); + exit(INSUFFICIENT_SPACE); + } + + /* precompute and cache, as invariant in loop below */ + Sparse_MatVec( (sparse_matrix*)Dinv, (real*)b, Dinv_b ); + + do + { + // x_{k+1} = G*x_{k} + Dinv*b; + Sparse_MatVec2( (sparse_matrix*)G, tri, x, x ); + Vector_Add2( x, Dinv_b, Dinv->n ); + ++iter; + } + while ( iter < maxiter ); + + free(Dinv_b); } /* generalized minimual residual iterative solver for sparse linear systems, * no preconditioner */ -int GMRES( static_storage *workspace, sparse_matrix *H, - real *b, real tol, real *x, FILE *fout ) +int GMRES( static_storage *workspace, sparse_matrix *H, + real *b, real tol, real *x, FILE *fout ) { - int i, j, k, itr, N; - real cc, tmp1, tmp2, temp, bnorm; - - N = H->n; - bnorm = Norm( b, N ); - /* apply the diagonal pre-conditioner to rhs */ - for( i = 0; i < N; ++i ) - workspace->b_prc[i] = b[i] * workspace->Hdia_inv[i]; - - /* GMRES outer-loop */ - for( itr = 0; itr < MAX_ITR; ++itr ) { - /* calculate r0 */ - Sparse_MatVec( H, x, workspace->b_prm ); - for( i = 0; i < N; ++i ) - workspace->b_prm[i] *= workspace->Hdia_inv[i]; /* pre-conditioner */ - - Vector_Sum(workspace->v[0], 1.,workspace->b_prc, -1., workspace->b_prm, N); - workspace->g[0] = Norm( workspace->v[0], N ); - Vector_Scale( workspace->v[0], 1. / workspace->g[0], workspace->v[0], N ); - //fprintf( stderr, "res: %.15e\n", workspace->g[0] ); - - /* GMRES inner-loop */ - for( j = 0; j < RESTART && fabs(workspace->g[j]) / bnorm > tol; j++ ) { - /* matvec */ - Sparse_MatVec( H, workspace->v[j], workspace->v[j+1] ); - for( k = 0; k < N; ++k ) - workspace->v[j+1][k] *= workspace->Hdia_inv[k]; /*pre-conditioner*/ - //fprintf( stderr, "%d-%d: matvec done.\n", itr, j ); - - /* apply modified Gram-Schmidt to orthogonalize the new residual */ - for( i = 0; i <= j; i++ ) { - workspace->h[i][j] = Dot( workspace->v[i], workspace->v[j+1], N ); - Vector_Add( workspace->v[j+1], - -workspace->h[i][j], workspace->v[i], N ); - } - - workspace->h[j+1][j] = Norm( workspace->v[j+1], N ); - Vector_Scale( workspace->v[j+1], - 1. / workspace->h[j+1][j], workspace->v[j+1], N ); - // fprintf( stderr, "%d-%d: orthogonalization completed.\n", itr, j ); - - - /* Givens rotations on the upper-Hessenberg matrix to make it U */ - for( i = 0; i <= j; i++ ) { - if( i == j ) { - cc = SQRT( SQR(workspace->h[j][j])+SQR(workspace->h[j+1][j]) ); - workspace->hc[j] = workspace->h[j][j] / cc; - workspace->hs[j] = workspace->h[j+1][j] / cc; - } - - tmp1 = workspace->hc[i] * workspace->h[i][j] + - workspace->hs[i] * workspace->h[i+1][j]; - tmp2 = -workspace->hs[i] * workspace->h[i][j] + - workspace->hc[i] * workspace->h[i+1][j]; - - workspace->h[i][j] = tmp1; - workspace->h[i+1][j] = tmp2; - } - - /* apply Givens rotations to the rhs as well */ - tmp1 = workspace->hc[j] * workspace->g[j]; - tmp2 = -workspace->hs[j] * workspace->g[j]; - workspace->g[j] = tmp1; - workspace->g[j+1] = tmp2; - - // fprintf( stderr, "h: " ); - // for( i = 0; i <= j+1; ++i ) - // fprintf( stderr, "%.6f ", workspace->h[i][j] ); - // fprintf( stderr, "\n" ); - //fprintf( stderr, "res: %.15e\n", workspace->g[j+1] ); + int i, j, k, itr, N; + real cc, tmp1, tmp2, temp, bnorm; + + N = H->n; + bnorm = Norm( b, N ); + /* apply the diagonal pre-conditioner to rhs */ + for ( i = 0; i < N; ++i ) + workspace->b_prc[i] = b[i] * workspace->Hdia_inv[i]; + + /* GMRES outer-loop */ + for ( itr = 0; itr < MAX_ITR; ++itr ) + { + /* calculate r0 */ + Sparse_MatVec( H, x, workspace->b_prm ); + for ( i = 0; i < N; ++i ) + workspace->b_prm[i] *= workspace->Hdia_inv[i]; /* pre-conditioner */ + + Vector_Sum(workspace->v[0], 1., workspace->b_prc, -1., workspace->b_prm, N); + workspace->g[0] = Norm( workspace->v[0], N ); + Vector_Scale( workspace->v[0], 1. / workspace->g[0], workspace->v[0], N ); + //fprintf( stderr, "res: %.15e\n", workspace->g[0] ); + + /* GMRES inner-loop */ + for ( j = 0; j < RESTART && fabs(workspace->g[j]) / bnorm > tol; j++ ) + { + /* matvec */ + Sparse_MatVec( H, workspace->v[j], workspace->v[j + 1] ); + for ( k = 0; k < N; ++k ) + workspace->v[j + 1][k] *= workspace->Hdia_inv[k]; /*pre-conditioner*/ + //fprintf( stderr, "%d-%d: matvec done.\n", itr, j ); + + /* apply modified Gram-Schmidt to orthogonalize the new residual */ + for ( i = 0; i <= j; i++ ) + { + workspace->h[i][j] = Dot( workspace->v[i], workspace->v[j + 1], N ); + Vector_Add( workspace->v[j + 1], + -workspace->h[i][j], workspace->v[i], N ); + } + + workspace->h[j + 1][j] = Norm( workspace->v[j + 1], N ); + Vector_Scale( workspace->v[j + 1], + 1. / workspace->h[j + 1][j], workspace->v[j + 1], N ); + // fprintf( stderr, "%d-%d: orthogonalization completed.\n", itr, j ); + + + /* Givens rotations on the upper-Hessenberg matrix to make it U */ + for ( i = 0; i <= j; i++ ) + { + if ( i == j ) + { + cc = SQRT( SQR(workspace->h[j][j]) + SQR(workspace->h[j + 1][j]) ); + workspace->hc[j] = workspace->h[j][j] / cc; + workspace->hs[j] = workspace->h[j + 1][j] / cc; + } + + tmp1 = workspace->hc[i] * workspace->h[i][j] + + workspace->hs[i] * workspace->h[i + 1][j]; + tmp2 = -workspace->hs[i] * workspace->h[i][j] + + workspace->hc[i] * workspace->h[i + 1][j]; + + workspace->h[i][j] = tmp1; + workspace->h[i + 1][j] = tmp2; + } + + /* apply Givens rotations to the rhs as well */ + tmp1 = workspace->hc[j] * workspace->g[j]; + tmp2 = -workspace->hs[j] * workspace->g[j]; + workspace->g[j] = tmp1; + workspace->g[j + 1] = tmp2; + + // fprintf( stderr, "h: " ); + // for( i = 0; i <= j+1; ++i ) + // fprintf( stderr, "%.6f ", workspace->h[i][j] ); + // fprintf( stderr, "\n" ); + //fprintf( stderr, "res: %.15e\n", workspace->g[j+1] ); + } + + + /* solve Hy = g. + H is now upper-triangular, do back-substitution */ + for ( i = j - 1; i >= 0; i-- ) + { + temp = workspace->g[i]; + for ( k = j - 1; k > i; k-- ) + temp -= workspace->h[i][k] * workspace->y[k]; + + workspace->y[i] = temp / workspace->h[i][i]; + } + + /* update x = x_0 + Vy */ + for ( i = 0; i < j; i++ ) + Vector_Add( x, workspace->y[i], workspace->v[i], N ); + + /* stopping condition */ + if ( fabs(workspace->g[j]) / bnorm <= tol ) + break; } - - - /* solve Hy = g. - H is now upper-triangular, do back-substitution */ - for( i = j-1; i >= 0; i-- ) { - temp = workspace->g[i]; - for( k = j-1; k > i; k-- ) - temp -= workspace->h[i][k] * workspace->y[k]; - - workspace->y[i] = temp / workspace->h[i][i]; + + // Sparse_MatVec( H, x, workspace->b_prm ); + // for( i = 0; i < N; ++i ) + // workspace->b_prm[i] *= workspace->Hdia_inv[i]; + // fprintf( fout, "\n%10s%15s%15s\n", "b_prc", "b_prm", "x" ); + // for( i = 0; i < N; ++i ) + // fprintf( fout, "%10.5f%15.12f%15.12f\n", + // workspace->b_prc[i], workspace->b_prm[i], x[i] );*/ + + // fprintf(fout,"GMRES outer:%d, inner:%d iters - residual norm: %25.20f\n", + // itr, j, fabs( workspace->g[j] ) / bnorm ); + // data->timing.matvec += itr * RESTART + j; + + if ( itr >= MAX_ITR ) + { + fprintf( stderr, "GMRES convergence failed\n" ); + // return -1; + return itr * (RESTART + 1) + j + 1; } - - /* update x = x_0 + Vy */ - for( i = 0; i < j; i++ ) - Vector_Add( x, workspace->y[i], workspace->v[i], N ); - - /* stopping condition */ - if( fabs(workspace->g[j]) / bnorm <= tol ) - break; - } - - // Sparse_MatVec( H, x, workspace->b_prm ); - // for( i = 0; i < N; ++i ) - // workspace->b_prm[i] *= workspace->Hdia_inv[i]; - // fprintf( fout, "\n%10s%15s%15s\n", "b_prc", "b_prm", "x" ); - // for( i = 0; i < N; ++i ) - // fprintf( fout, "%10.5f%15.12f%15.12f\n", - // workspace->b_prc[i], workspace->b_prm[i], x[i] );*/ - - // fprintf(fout,"GMRES outer:%d, inner:%d iters - residual norm: %25.20f\n", - // itr, j, fabs( workspace->g[j] ) / bnorm ); - // data->timing.matvec += itr * RESTART + j; - - if( itr >= MAX_ITR ) { - fprintf( stderr, "GMRES convergence failed\n" ); - // return -1; - return itr * (RESTART+1) + j + 1; - } - - return itr * (RESTART+1) + j + 1; + + return itr * (RESTART + 1) + j + 1; } -int GMRES_HouseHolder( static_storage *workspace, sparse_matrix *H, - real *b, real tol, real *x, FILE *fout) +int GMRES_HouseHolder( static_storage *workspace, sparse_matrix *H, + real *b, real tol, real *x, FILE *fout) { - int i, j, k, itr, N; - real cc, tmp1, tmp2, temp, bnorm; - real v[10000], z[RESTART+2][10000], w[RESTART+2]; - real u[RESTART+2][10000]; - - N = H->n; - bnorm = Norm( b, N ); - - /* apply the diagonal pre-conditioner to rhs */ - for( i = 0; i < N; ++i ) - workspace->b_prc[i] = b[i] * workspace->Hdia_inv[i]; - - // memset( x, 0, sizeof(real) * N ); - - /* GMRES outer-loop */ - for( itr = 0; itr < MAX_ITR; ++itr ) { - /* compute z = r0 */ - Sparse_MatVec( H, x, workspace->b_prm ); - for( i = 0; i < N; ++i ) - workspace->b_prm[i] *= workspace->Hdia_inv[i]; /* pre-conditioner */ - Vector_Sum( z[0], 1., workspace->b_prc, -1., workspace->b_prm, N ); - - Vector_MakeZero( w, RESTART+1 ); - w[0] = Norm( z[0], N ); - - Vector_Copy( u[0], z[0], N ); - u[0][0] += ( u[0][0] < 0.0 ? -1 : 1 ) * w[0]; - Vector_Scale( u[0], 1 / Norm( u[0], N ), u[0], N ); - - w[0] *= ( u[0][0] < 0.0 ? 1 :-1 ); - // fprintf( stderr, "\n\n%12.6f\n", w[0] ); - - /* GMRES inner-loop */ - for( j = 0; j < RESTART && fabs( w[j] ) / bnorm > tol; j++ ) { - /* compute v_j */ - Vector_Scale( z[j], -2 * u[j][j], u[j], N ); - z[j][j] += 1.; /* due to e_j */ - - for( i = j-1; i >= 0; --i ) - Vector_Add( z[j]+i, -2 * Dot( u[i]+i, z[j]+i, N-i ), u[i]+i, N-i ); - - - /* matvec */ - Sparse_MatVec( H, z[j], v ); - - for( k = 0; k < N; ++k ) - v[k] *= workspace->Hdia_inv[k]; /* pre-conditioner */ - - for( i = 0; i <= j; ++i ) - Vector_Add( v+i, -2 * Dot( u[i]+i, v+i, N-i ), u[i]+i, N-i ); - - - if( !Vector_isZero( v + (j+1), N - (j+1) ) ) { - /* compute the HouseHolder unit vector u_j+1 */ - for( i = 0; i <= j; ++i ) - u[j+1][i] = 0; - - Vector_Copy( u[j+1] + (j+1), v + (j+1), N - (j+1) ); - - u[j+1][j+1] += ( v[j+1]<0.0 ? -1:1 ) * Norm( v+(j+1), N-(j+1) ); - - Vector_Scale( u[j+1], 1 / Norm( u[j+1], N ), u[j+1], N ); - - /* overwrite v with P_m+1 * v */ - v[j+1] -= 2 * Dot( u[j+1]+(j+1), v+(j+1), N-(j+1) ) * u[j+1][j+1]; - Vector_MakeZero( v + (j+2), N - (j+2) ); - // Vector_Add( v, -2 * Dot( u[j+1], v, N ), u[j+1], N ); - } - - - /* prev Givens rots on the upper-Hessenberg matrix to make it U */ - for( i = 0; i < j; i++ ) { - tmp1 = workspace->hc[i] * v[i] + workspace->hs[i] * v[i+1]; - tmp2 = -workspace->hs[i] * v[i] + workspace->hc[i] * v[i+1]; - - v[i] = tmp1; - v[i+1] = tmp2; - } - - /* apply the new Givens rotation to H and right-hand side */ - if( fabs(v[j+1]) >= ALMOST_ZERO ) { - cc = SQRT( SQR( v[j] ) + SQR( v[j+1] ) ); - workspace->hc[j] = v[j] / cc; - workspace->hs[j] = v[j+1] / cc; - - tmp1 = workspace->hc[j] * v[j] + workspace->hs[j] * v[j+1]; - tmp2 = -workspace->hs[j] * v[j] + workspace->hc[j] * v[j+1]; - - v[j] = tmp1; - v[j+1] = tmp2; - - /* Givens rotations to rhs */ - tmp1 = workspace->hc[j] * w[j]; - tmp2 = -workspace->hs[j] * w[j]; - w[j] = tmp1; - w[j+1] = tmp2; - } - - /* extend R */ - for( i = 0; i <= j; ++i ) - workspace->h[i][j] = v[i]; - - - // fprintf( stderr, "h:" ); - // for( i = 0; i <= j+1 ; ++i ) - // fprintf( stderr, "%.6f ", h[i][j] ); - // fprintf( stderr, "\n" ); - // fprintf( stderr, "%12.6f\n", w[j+1] ); - } - - - /* solve Hy = w. - H is now upper-triangular, do back-substitution */ - for( i = j-1; i >= 0; i-- ) { - temp = w[i]; - for( k = j-1; k > i; k-- ) - temp -= workspace->h[i][k] * workspace->y[k]; - - workspace->y[i] = temp / workspace->h[i][i]; + int i, j, k, itr, N; + real cc, tmp1, tmp2, temp, bnorm; + real v[10000], z[RESTART + 2][10000], w[RESTART + 2]; + real u[RESTART + 2][10000]; + + N = H->n; + bnorm = Norm( b, N ); + + /* apply the diagonal pre-conditioner to rhs */ + for ( i = 0; i < N; ++i ) + workspace->b_prc[i] = b[i] * workspace->Hdia_inv[i]; + + // memset( x, 0, sizeof(real) * N ); + + /* GMRES outer-loop */ + for ( itr = 0; itr < MAX_ITR; ++itr ) + { + /* compute z = r0 */ + Sparse_MatVec( H, x, workspace->b_prm ); + for ( i = 0; i < N; ++i ) + workspace->b_prm[i] *= workspace->Hdia_inv[i]; /* pre-conditioner */ + Vector_Sum( z[0], 1., workspace->b_prc, -1., workspace->b_prm, N ); + + Vector_MakeZero( w, RESTART + 1 ); + w[0] = Norm( z[0], N ); + + Vector_Copy( u[0], z[0], N ); + u[0][0] += ( u[0][0] < 0.0 ? -1 : 1 ) * w[0]; + Vector_Scale( u[0], 1 / Norm( u[0], N ), u[0], N ); + + w[0] *= ( u[0][0] < 0.0 ? 1 : -1 ); + // fprintf( stderr, "\n\n%12.6f\n", w[0] ); + + /* GMRES inner-loop */ + for ( j = 0; j < RESTART && fabs( w[j] ) / bnorm > tol; j++ ) + { + /* compute v_j */ + Vector_Scale( z[j], -2 * u[j][j], u[j], N ); + z[j][j] += 1.; /* due to e_j */ + + for ( i = j - 1; i >= 0; --i ) + Vector_Add( z[j] + i, -2 * Dot( u[i] + i, z[j] + i, N - i ), u[i] + i, N - i ); + + + /* matvec */ + Sparse_MatVec( H, z[j], v ); + + for ( k = 0; k < N; ++k ) + v[k] *= workspace->Hdia_inv[k]; /* pre-conditioner */ + + for ( i = 0; i <= j; ++i ) + Vector_Add( v + i, -2 * Dot( u[i] + i, v + i, N - i ), u[i] + i, N - i ); + + + if ( !Vector_isZero( v + (j + 1), N - (j + 1) ) ) + { + /* compute the HouseHolder unit vector u_j+1 */ + for ( i = 0; i <= j; ++i ) + u[j + 1][i] = 0; + + Vector_Copy( u[j + 1] + (j + 1), v + (j + 1), N - (j + 1) ); + + u[j + 1][j + 1] += ( v[j + 1] < 0.0 ? -1 : 1 ) * Norm( v + (j + 1), N - (j + 1) ); + + Vector_Scale( u[j + 1], 1 / Norm( u[j + 1], N ), u[j + 1], N ); + + /* overwrite v with P_m+1 * v */ + v[j + 1] -= 2 * Dot( u[j + 1] + (j + 1), v + (j + 1), N - (j + 1) ) * u[j + 1][j + 1]; + Vector_MakeZero( v + (j + 2), N - (j + 2) ); + // Vector_Add( v, -2 * Dot( u[j+1], v, N ), u[j+1], N ); + } + + + /* prev Givens rots on the upper-Hessenberg matrix to make it U */ + for ( i = 0; i < j; i++ ) + { + tmp1 = workspace->hc[i] * v[i] + workspace->hs[i] * v[i + 1]; + tmp2 = -workspace->hs[i] * v[i] + workspace->hc[i] * v[i + 1]; + + v[i] = tmp1; + v[i + 1] = tmp2; + } + + /* apply the new Givens rotation to H and right-hand side */ + if ( fabs(v[j + 1]) >= ALMOST_ZERO ) + { + cc = SQRT( SQR( v[j] ) + SQR( v[j + 1] ) ); + workspace->hc[j] = v[j] / cc; + workspace->hs[j] = v[j + 1] / cc; + + tmp1 = workspace->hc[j] * v[j] + workspace->hs[j] * v[j + 1]; + tmp2 = -workspace->hs[j] * v[j] + workspace->hc[j] * v[j + 1]; + + v[j] = tmp1; + v[j + 1] = tmp2; + + /* Givens rotations to rhs */ + tmp1 = workspace->hc[j] * w[j]; + tmp2 = -workspace->hs[j] * w[j]; + w[j] = tmp1; + w[j + 1] = tmp2; + } + + /* extend R */ + for ( i = 0; i <= j; ++i ) + workspace->h[i][j] = v[i]; + + + // fprintf( stderr, "h:" ); + // for( i = 0; i <= j+1 ; ++i ) + // fprintf( stderr, "%.6f ", h[i][j] ); + // fprintf( stderr, "\n" ); + // fprintf( stderr, "%12.6f\n", w[j+1] ); + } + + + /* solve Hy = w. + H is now upper-triangular, do back-substitution */ + for ( i = j - 1; i >= 0; i-- ) + { + temp = w[i]; + for ( k = j - 1; k > i; k-- ) + temp -= workspace->h[i][k] * workspace->y[k]; + + workspace->y[i] = temp / workspace->h[i][i]; + } + + // fprintf( stderr, "y: " ); + // for( i = 0; i < RESTART+1; ++i ) + // fprintf( stderr, "%8.3f ", workspace->y[i] ); + + + /* update x = x_0 + Vy */ + // memset( z, 0, sizeof(real) * N ); + // for( i = j-1; i >= 0; i-- ) + // { + // Vector_Copy( v, z, N ); + // v[i] += workspace->y[i]; + // + // Vector_Sum( z, 1., v, -2 * Dot( u[i], v, N ), u[i], N ); + // } + // + // fprintf( stderr, "\nz: " ); + // for( k = 0; k < N; ++k ) + // fprintf( stderr, "%6.2f ", z[k] ); + + // fprintf( stderr, "\nx_bef: " ); + // for( i = 0; i < N; ++i ) + // fprintf( stderr, "%6.2f ", x[i] ); + + // Vector_Add( x, 1, z, N ); + for ( i = j - 1; i >= 0; i-- ) + Vector_Add( x, workspace->y[i], z[i], N ); + + // fprintf( stderr, "\nx_aft: " ); + // for( i = 0; i < N; ++i ) + // fprintf( stderr, "%6.2f ", x[i] ); + + /* stopping condition */ + if ( fabs( w[j] ) / bnorm <= tol ) + break; } - - // fprintf( stderr, "y: " ); - // for( i = 0; i < RESTART+1; ++i ) - // fprintf( stderr, "%8.3f ", workspace->y[i] ); - - - /* update x = x_0 + Vy */ - // memset( z, 0, sizeof(real) * N ); - // for( i = j-1; i >= 0; i-- ) - // { - // Vector_Copy( v, z, N ); - // v[i] += workspace->y[i]; - // - // Vector_Sum( z, 1., v, -2 * Dot( u[i], v, N ), u[i], N ); - // } - // - // fprintf( stderr, "\nz: " ); - // for( k = 0; k < N; ++k ) - // fprintf( stderr, "%6.2f ", z[k] ); - - // fprintf( stderr, "\nx_bef: " ); + + // Sparse_MatVec( H, x, workspace->b_prm ); // for( i = 0; i < N; ++i ) - // fprintf( stderr, "%6.2f ", x[i] ); - - // Vector_Add( x, 1, z, N ); - for( i = j-1; i >= 0; i-- ) - Vector_Add( x, workspace->y[i], z[i], N ); - - // fprintf( stderr, "\nx_aft: " ); + // workspace->b_prm[i] *= workspace->Hdia_inv[i]; + + // fprintf( fout, "\n%10s%15s%15s\n", "b_prc", "b_prm", "x" ); // for( i = 0; i < N; ++i ) - // fprintf( stderr, "%6.2f ", x[i] ); - - /* stopping condition */ - if( fabs( w[j] ) / bnorm <= tol ) - break; - } - - // Sparse_MatVec( H, x, workspace->b_prm ); - // for( i = 0; i < N; ++i ) - // workspace->b_prm[i] *= workspace->Hdia_inv[i]; - - // fprintf( fout, "\n%10s%15s%15s\n", "b_prc", "b_prm", "x" ); - // for( i = 0; i < N; ++i ) - // fprintf( fout, "%10.5f%15.12f%15.12f\n", - // workspace->b_prc[i], workspace->b_prm[i], x[i] ); - - //fprintf( fout,"GMRES outer:%d, inner:%d iters - residual norm: %15.10f\n", - // itr, j, fabs( workspace->g[j] ) / bnorm ); - - if( itr >= MAX_ITR ) { - fprintf( stderr, "GMRES convergence failed\n" ); - // return -1; - return itr * (RESTART+1) + j + 1; - } - - return itr * (RESTART+1) + j + 1; + // fprintf( fout, "%10.5f%15.12f%15.12f\n", + // workspace->b_prc[i], workspace->b_prm[i], x[i] ); + + //fprintf( fout,"GMRES outer:%d, inner:%d iters - residual norm: %15.10f\n", + // itr, j, fabs( workspace->g[j] ) / bnorm ); + + if ( itr >= MAX_ITR ) + { + fprintf( stderr, "GMRES convergence failed\n" ); + // return -1; + return itr * (RESTART + 1) + j + 1; + } + + return itr * (RESTART + 1) + j + 1; } /* generalized minimual residual iterative solver for sparse linear systems, * with preconditioner using factors LU \approx H * and forward / backward substitution */ -int PGMRES( static_storage *workspace, sparse_matrix *H, real *b, real tol, - sparse_matrix *L, sparse_matrix *U, real *x, FILE *fout ) +int PGMRES( static_storage *workspace, sparse_matrix *H, real *b, real tol, + sparse_matrix *L, sparse_matrix *U, real *x, FILE *fout ) { - int i, j, k, itr, N; - real cc, tmp1, tmp2, temp, bnorm; - - N = H->n; - bnorm = Norm( b, N ); - - /* GMRES outer-loop */ - for( itr = 0; itr < MAX_ITR; ++itr ) { - /* calculate r0 */ - Sparse_MatVec( H, x, workspace->b_prm ); - Vector_Sum( workspace->v[0], 1., b, -1., workspace->b_prm, N ); - Forward_Subs( L, workspace->v[0], workspace->v[0] ); - Backward_Subs( U, workspace->v[0], workspace->v[0] ); - workspace->g[0] = Norm( workspace->v[0], N ); - Vector_Scale( workspace->v[0], 1. / workspace->g[0], workspace->v[0], N ); - //fprintf( stderr, "res: %.15e\n", workspace->g[0] ); - - /* GMRES inner-loop */ - for( j = 0; j < RESTART && fabs(workspace->g[j]) / bnorm > tol; j++ ) { - /* matvec */ - Sparse_MatVec( H, workspace->v[j], workspace->v[j+1] ); - Forward_Subs( L, workspace->v[j+1], workspace->v[j+1] ); - Backward_Subs( U, workspace->v[j+1], workspace->v[j+1] ); - - /* apply modified Gram-Schmidt to orthogonalize the new residual */ - for( i = 0; i < j-1; i++ ) workspace->h[i][j] = 0; - - //for( i = 0; i <= j; i++ ) { - for( i = MAX(j-1,0); i <= j; i++ ) { - workspace->h[i][j] = Dot( workspace->v[i], workspace->v[j+1], N ); - Vector_Add( workspace->v[j+1],-workspace->h[i][j], workspace->v[i], N ); - } - - workspace->h[j+1][j] = Norm( workspace->v[j+1], N ); - Vector_Scale( workspace->v[j+1], - 1. / workspace->h[j+1][j], workspace->v[j+1], N ); - // fprintf( stderr, "%d-%d: orthogonalization completed.\n", itr, j ); - - /* Givens rotations on the upper-Hessenberg matrix to make it U */ - for( i = MAX(j-1,0); i <= j; i++ ) { - if( i == j ) { - cc = SQRT( SQR(workspace->h[j][j])+SQR(workspace->h[j+1][j]) ); - workspace->hc[j] = workspace->h[j][j] / cc; - workspace->hs[j] = workspace->h[j+1][j] / cc; - } - - tmp1 = workspace->hc[i] * workspace->h[i][j] + - workspace->hs[i] * workspace->h[i+1][j]; - tmp2 = -workspace->hs[i] * workspace->h[i][j] + - workspace->hc[i] * workspace->h[i+1][j]; - - workspace->h[i][j] = tmp1; - workspace->h[i+1][j] = tmp2; - } - - /* apply Givens rotations to the rhs as well */ - tmp1 = workspace->hc[j] * workspace->g[j]; - tmp2 = -workspace->hs[j] * workspace->g[j]; - workspace->g[j] = tmp1; - workspace->g[j+1] = tmp2; - - //fprintf( stderr, "h: " ); - //for( i = 0; i <= j+1; ++i ) - //fprintf( stderr, "%.6f ", workspace->h[i][j] ); - //fprintf( stderr, "\n" ); - //fprintf( stderr, "res: %.15e\n", workspace->g[j+1] ); + int i, j, k, itr, N; + real cc, tmp1, tmp2, temp, bnorm; + + N = H->n; + bnorm = Norm( b, N ); + + /* GMRES outer-loop */ + for ( itr = 0; itr < MAX_ITR; ++itr ) + { + /* calculate r0 */ + Sparse_MatVec( H, x, workspace->b_prm ); + Vector_Sum( workspace->v[0], 1., b, -1., workspace->b_prm, N ); + Forward_Subs( L, workspace->v[0], workspace->v[0] ); + Backward_Subs( U, workspace->v[0], workspace->v[0] ); + workspace->g[0] = Norm( workspace->v[0], N ); + Vector_Scale( workspace->v[0], 1. / workspace->g[0], workspace->v[0], N ); + //fprintf( stderr, "res: %.15e\n", workspace->g[0] ); + + /* GMRES inner-loop */ + for ( j = 0; j < RESTART && fabs(workspace->g[j]) / bnorm > tol; j++ ) + { + /* matvec */ + Sparse_MatVec( H, workspace->v[j], workspace->v[j + 1] ); + Forward_Subs( L, workspace->v[j + 1], workspace->v[j + 1] ); + Backward_Subs( U, workspace->v[j + 1], workspace->v[j + 1] ); + + /* apply modified Gram-Schmidt to orthogonalize the new residual */ + for ( i = 0; i < j - 1; i++ ) workspace->h[i][j] = 0; + + //for( i = 0; i <= j; i++ ) { + for ( i = MAX(j - 1, 0); i <= j; i++ ) + { + workspace->h[i][j] = Dot( workspace->v[i], workspace->v[j + 1], N ); + Vector_Add( workspace->v[j + 1], -workspace->h[i][j], workspace->v[i], N ); + } + + workspace->h[j + 1][j] = Norm( workspace->v[j + 1], N ); + Vector_Scale( workspace->v[j + 1], + 1. / workspace->h[j + 1][j], workspace->v[j + 1], N ); + // fprintf( stderr, "%d-%d: orthogonalization completed.\n", itr, j ); + + /* Givens rotations on the upper-Hessenberg matrix to make it U */ + for ( i = MAX(j - 1, 0); i <= j; i++ ) + { + if ( i == j ) + { + cc = SQRT( SQR(workspace->h[j][j]) + SQR(workspace->h[j + 1][j]) ); + workspace->hc[j] = workspace->h[j][j] / cc; + workspace->hs[j] = workspace->h[j + 1][j] / cc; + } + + tmp1 = workspace->hc[i] * workspace->h[i][j] + + workspace->hs[i] * workspace->h[i + 1][j]; + tmp2 = -workspace->hs[i] * workspace->h[i][j] + + workspace->hc[i] * workspace->h[i + 1][j]; + + workspace->h[i][j] = tmp1; + workspace->h[i + 1][j] = tmp2; + } + + /* apply Givens rotations to the rhs as well */ + tmp1 = workspace->hc[j] * workspace->g[j]; + tmp2 = -workspace->hs[j] * workspace->g[j]; + workspace->g[j] = tmp1; + workspace->g[j + 1] = tmp2; + + //fprintf( stderr, "h: " ); + //for( i = 0; i <= j+1; ++i ) + //fprintf( stderr, "%.6f ", workspace->h[i][j] ); + //fprintf( stderr, "\n" ); + //fprintf( stderr, "res: %.15e\n", workspace->g[j+1] ); + } + + + /* solve Hy = g: H is now upper-triangular, do back-substitution */ + for ( i = j - 1; i >= 0; i-- ) + { + temp = workspace->g[i]; + for ( k = j - 1; k > i; k-- ) + temp -= workspace->h[i][k] * workspace->y[k]; + + workspace->y[i] = temp / workspace->h[i][i]; + } + + /* update x = x_0 + Vy */ + Vector_MakeZero( workspace->p, N ); + for ( i = 0; i < j; i++ ) + Vector_Add( workspace->p, workspace->y[i], workspace->v[i], N ); + //Backward_Subs( U, workspace->p, workspace->p ); + //Forward_Subs( L, workspace->p, workspace->p ); + Vector_Add( x, 1., workspace->p, N ); + + /* stopping condition */ + if ( fabs(workspace->g[j]) / bnorm <= tol ) + break; } - - - /* solve Hy = g: H is now upper-triangular, do back-substitution */ - for( i = j-1; i >= 0; i-- ) { - temp = workspace->g[i]; - for( k = j-1; k > i; k-- ) - temp -= workspace->h[i][k] * workspace->y[k]; - - workspace->y[i] = temp / workspace->h[i][i]; + + // Sparse_MatVec( H, x, workspace->b_prm ); + // for( i = 0; i < N; ++i ) + // workspace->b_prm[i] *= workspace->Hdia_inv[i]; + // fprintf( fout, "\n%10s%15s%15s\n", "b_prc", "b_prm", "x" ); + // for( i = 0; i < N; ++i ) + // fprintf( fout, "%10.5f%15.12f%15.12f\n", + // workspace->b_prc[i], workspace->b_prm[i], x[i] );*/ + + // fprintf(fout,"GMRES outer:%d, inner:%d iters - residual norm: %25.20f\n", + // itr, j, fabs( workspace->g[j] ) / bnorm ); + // data->timing.matvec += itr * RESTART + j; + + if ( itr >= MAX_ITR ) + { + fprintf( stderr, "GMRES convergence failed\n" ); + // return -1; + return itr * (RESTART + 1) + j + 1; } - - /* update x = x_0 + Vy */ - Vector_MakeZero( workspace->p, N ); - for( i = 0; i < j; i++ ) - Vector_Add( workspace->p, workspace->y[i], workspace->v[i], N ); - //Backward_Subs( U, workspace->p, workspace->p ); - //Forward_Subs( L, workspace->p, workspace->p ); - Vector_Add( x, 1., workspace->p, N ); - - /* stopping condition */ - if( fabs(workspace->g[j]) / bnorm <= tol ) - break; - } - - // Sparse_MatVec( H, x, workspace->b_prm ); - // for( i = 0; i < N; ++i ) - // workspace->b_prm[i] *= workspace->Hdia_inv[i]; - // fprintf( fout, "\n%10s%15s%15s\n", "b_prc", "b_prm", "x" ); - // for( i = 0; i < N; ++i ) - // fprintf( fout, "%10.5f%15.12f%15.12f\n", - // workspace->b_prc[i], workspace->b_prm[i], x[i] );*/ - - // fprintf(fout,"GMRES outer:%d, inner:%d iters - residual norm: %25.20f\n", - // itr, j, fabs( workspace->g[j] ) / bnorm ); - // data->timing.matvec += itr * RESTART + j; - - if( itr >= MAX_ITR ) { - fprintf( stderr, "GMRES convergence failed\n" ); - // return -1; - return itr * (RESTART+1) + j + 1; - } - - return itr * (RESTART+1) + j + 1; + + return itr * (RESTART + 1) + j + 1; } /* generalized minimual residual iterative solver for sparse linear systems, * with preconditioner using factors LU \approx H * and Jacobi iteration for approximate factor application */ -int PGMRES_Jacobi( static_storage *workspace, sparse_matrix *H, real *b, real tol, - sparse_matrix *L, sparse_matrix *U, real *x, FILE *fout ) +int PGMRES_Jacobi( static_storage *workspace, sparse_matrix *H, real *b, real tol, + sparse_matrix *L, sparse_matrix *U, real *x, FILE *fout ) { - int i, j, k, itr, N, pj, si, ei; - real cc, tmp1, tmp2, temp, bnorm; - sparse_matrix *Dinv_L, *Dinv_U; - - N = H->n; - bnorm = Norm( b, N ); - - /* Compute Jacobi iteration matrices from - * truncated Newmann series: x_{k+1} = Gx_k + D^{-1}b - * where: - * G = I - D^{-1}R - * R = triangular matrix - * D = diagonal matrix, diagonals from R */ - if( Allocate_Matrix( &Dinv_L, L->n, L->n ) == 0 || - Allocate_Matrix( &Dinv_U, U->n, U->n ) == 0 ) - { - fprintf( stderr, "not enough memory for Jacobi iteration matrices. terminating.\n" ); - exit(INSUFFICIENT_SPACE); - } - - /* construct D^{-1}_L and D^{-1}_U */ - for( i = 0; i < N; ++i ) - { - si = L->start[i+1]-1; - Dinv_L->start[i] = i; - Dinv_L->entries[i].j = i; - Dinv_L->entries[i].val = 1. / L->entries[si].val; - - si = U->start[i]; - Dinv_U->start[i] = i; - Dinv_U->entries[i].j = i; - Dinv_U->entries[i].val = 1. / U->entries[si].val; - } - Dinv_L->start[N] = N; - Dinv_U->start[N] = N; - - /* GMRES outer-loop */ - for( itr = 0; itr < MAX_ITR; ++itr ) { - /* calculate r0 */ - Sparse_MatVec( H, x, workspace->b_prm ); - Vector_Sum( workspace->v[0], 1., b, -1., workspace->b_prm, N ); - // TODO: add parameters to config file - // TODO: cache results and use for inital guess? - Jacobi_Iter( (const sparse_matrix*)L, LOWER, (const sparse_matrix*)Dinv_L, - (const real*)workspace->v[0], workspace->v[0], 100 ); - Jacobi_Iter( (const sparse_matrix*)U, UPPER, (const sparse_matrix*)Dinv_U, - (const real*)workspace->v[0], workspace->v[0], 100 ); - workspace->g[0] = Norm( workspace->v[0], N ); - Vector_Scale( workspace->v[0], 1. / workspace->g[0], workspace->v[0], N ); - //fprintf( stderr, "res: %.15e\n", workspace->g[0] ); - - /* GMRES inner-loop */ - for( j = 0; j < RESTART && fabs(workspace->g[j]) / bnorm > tol; j++ ) { - /* matvec */ - Sparse_MatVec( H, workspace->v[j], workspace->v[j+1] ); - // TODO: add parameters to config file - // TODO: cache results and use for inital guess? - Jacobi_Iter( (const sparse_matrix*)L, LOWER, (const sparse_matrix*)Dinv_L, - (const real*)workspace->v[j+1], workspace->v[j+1], 100 ); - Jacobi_Iter( (const sparse_matrix*)U, UPPER, (const sparse_matrix*)Dinv_U, - (const real*)workspace->v[j+1], workspace->v[j+1], 100 ); - - /* apply modified Gram-Schmidt to orthogonalize the new residual */ - for( i = 0; i < j-1; i++ ) workspace->h[i][j] = 0; - - //for( i = 0; i <= j; i++ ) { - for( i = MAX(j-1,0); i <= j; i++ ) { - workspace->h[i][j] = Dot( workspace->v[i], workspace->v[j+1], N ); - Vector_Add( workspace->v[j+1],-workspace->h[i][j], workspace->v[i], N ); - } - - workspace->h[j+1][j] = Norm( workspace->v[j+1], N ); - Vector_Scale( workspace->v[j+1], - 1. / workspace->h[j+1][j], workspace->v[j+1], N ); - // fprintf( stderr, "%d-%d: orthogonalization completed.\n", itr, j ); - - /* Givens rotations on the upper-Hessenberg matrix to make it U */ - for( i = MAX(j-1,0); i <= j; i++ ) { - if( i == j ) { - cc = SQRT( SQR(workspace->h[j][j])+SQR(workspace->h[j+1][j]) ); - workspace->hc[j] = workspace->h[j][j] / cc; - workspace->hs[j] = workspace->h[j+1][j] / cc; - } - - tmp1 = workspace->hc[i] * workspace->h[i][j] + - workspace->hs[i] * workspace->h[i+1][j]; - tmp2 = -workspace->hs[i] * workspace->h[i][j] + - workspace->hc[i] * workspace->h[i+1][j]; - - workspace->h[i][j] = tmp1; - workspace->h[i+1][j] = tmp2; - } - - /* apply Givens rotations to the rhs as well */ - tmp1 = workspace->hc[j] * workspace->g[j]; - tmp2 = -workspace->hs[j] * workspace->g[j]; - workspace->g[j] = tmp1; - workspace->g[j+1] = tmp2; - - //fprintf( stderr, "h: " ); - //for( i = 0; i <= j+1; ++i ) - //fprintf( stderr, "%.6f ", workspace->h[i][j] ); - //fprintf( stderr, "\n" ); - //fprintf( stderr, "res: %.15e\n", workspace->g[j+1] ); + int i, j, k, itr, N, pj, si, ei; + real cc, tmp1, tmp2, temp, bnorm; + sparse_matrix *Dinv_L, *Dinv_U; + + N = H->n; + bnorm = Norm( b, N ); + + /* Compute Jacobi iteration matrices from + * truncated Newmann series: x_{k+1} = Gx_k + D^{-1}b + * where: + * G = I - D^{-1}R + * R = triangular matrix + * D = diagonal matrix, diagonals from R */ + if ( Allocate_Matrix( &Dinv_L, L->n, L->n ) == 0 || + Allocate_Matrix( &Dinv_U, U->n, U->n ) == 0 ) + { + fprintf( stderr, "not enough memory for Jacobi iteration matrices. terminating.\n" ); + exit(INSUFFICIENT_SPACE); + } + + /* construct D^{-1}_L and D^{-1}_U */ + for ( i = 0; i < N; ++i ) + { + si = L->start[i + 1] - 1; + Dinv_L->start[i] = i; + Dinv_L->entries[i].j = i; + Dinv_L->entries[i].val = 1. / L->entries[si].val; + + si = U->start[i]; + Dinv_U->start[i] = i; + Dinv_U->entries[i].j = i; + Dinv_U->entries[i].val = 1. / U->entries[si].val; } - - - /* solve Hy = g: H is now upper-triangular, do back-substitution */ - for( i = j-1; i >= 0; i-- ) { - temp = workspace->g[i]; - for( k = j-1; k > i; k-- ) - temp -= workspace->h[i][k] * workspace->y[k]; - - workspace->y[i] = temp / workspace->h[i][i]; + Dinv_L->start[N] = N; + Dinv_U->start[N] = N; + + /* GMRES outer-loop */ + for ( itr = 0; itr < MAX_ITR; ++itr ) + { + /* calculate r0 */ + Sparse_MatVec( H, x, workspace->b_prm ); + Vector_Sum( workspace->v[0], 1., b, -1., workspace->b_prm, N ); + // TODO: add parameters to config file + // TODO: cache results and use for inital guess? + Jacobi_Iter( (const sparse_matrix*)L, LOWER, (const sparse_matrix*)Dinv_L, + (const real*)workspace->v[0], workspace->v[0], 100 ); + Jacobi_Iter( (const sparse_matrix*)U, UPPER, (const sparse_matrix*)Dinv_U, + (const real*)workspace->v[0], workspace->v[0], 100 ); + workspace->g[0] = Norm( workspace->v[0], N ); + Vector_Scale( workspace->v[0], 1. / workspace->g[0], workspace->v[0], N ); + //fprintf( stderr, "res: %.15e\n", workspace->g[0] ); + + /* GMRES inner-loop */ + for ( j = 0; j < RESTART && fabs(workspace->g[j]) / bnorm > tol; j++ ) + { + /* matvec */ + Sparse_MatVec( H, workspace->v[j], workspace->v[j + 1] ); + // TODO: add parameters to config file + // TODO: cache results and use for inital guess? + Jacobi_Iter( (const sparse_matrix*)L, LOWER, (const sparse_matrix*)Dinv_L, + (const real*)workspace->v[j + 1], workspace->v[j + 1], 100 ); + Jacobi_Iter( (const sparse_matrix*)U, UPPER, (const sparse_matrix*)Dinv_U, + (const real*)workspace->v[j + 1], workspace->v[j + 1], 100 ); + + /* apply modified Gram-Schmidt to orthogonalize the new residual */ + for ( i = 0; i < j - 1; i++ ) workspace->h[i][j] = 0; + + //for( i = 0; i <= j; i++ ) { + for ( i = MAX(j - 1, 0); i <= j; i++ ) + { + workspace->h[i][j] = Dot( workspace->v[i], workspace->v[j + 1], N ); + Vector_Add( workspace->v[j + 1], -workspace->h[i][j], workspace->v[i], N ); + } + + workspace->h[j + 1][j] = Norm( workspace->v[j + 1], N ); + Vector_Scale( workspace->v[j + 1], + 1. / workspace->h[j + 1][j], workspace->v[j + 1], N ); + // fprintf( stderr, "%d-%d: orthogonalization completed.\n", itr, j ); + + /* Givens rotations on the upper-Hessenberg matrix to make it U */ + for ( i = MAX(j - 1, 0); i <= j; i++ ) + { + if ( i == j ) + { + cc = SQRT( SQR(workspace->h[j][j]) + SQR(workspace->h[j + 1][j]) ); + workspace->hc[j] = workspace->h[j][j] / cc; + workspace->hs[j] = workspace->h[j + 1][j] / cc; + } + + tmp1 = workspace->hc[i] * workspace->h[i][j] + + workspace->hs[i] * workspace->h[i + 1][j]; + tmp2 = -workspace->hs[i] * workspace->h[i][j] + + workspace->hc[i] * workspace->h[i + 1][j]; + + workspace->h[i][j] = tmp1; + workspace->h[i + 1][j] = tmp2; + } + + /* apply Givens rotations to the rhs as well */ + tmp1 = workspace->hc[j] * workspace->g[j]; + tmp2 = -workspace->hs[j] * workspace->g[j]; + workspace->g[j] = tmp1; + workspace->g[j + 1] = tmp2; + + //fprintf( stderr, "h: " ); + //for( i = 0; i <= j+1; ++i ) + //fprintf( stderr, "%.6f ", workspace->h[i][j] ); + //fprintf( stderr, "\n" ); + //fprintf( stderr, "res: %.15e\n", workspace->g[j+1] ); + } + + + /* solve Hy = g: H is now upper-triangular, do back-substitution */ + for ( i = j - 1; i >= 0; i-- ) + { + temp = workspace->g[i]; + for ( k = j - 1; k > i; k-- ) + temp -= workspace->h[i][k] * workspace->y[k]; + + workspace->y[i] = temp / workspace->h[i][i]; + } + + /* update x = x_0 + Vy */ + Vector_MakeZero( workspace->p, N ); + for ( i = 0; i < j; i++ ) + Vector_Add( workspace->p, workspace->y[i], workspace->v[i], N ); + //Backward_Subs( U, workspace->p, workspace->p ); + //Forward_Subs( L, workspace->p, workspace->p ); + Vector_Add( x, 1., workspace->p, N ); + + /* stopping condition */ + if ( fabs(workspace->g[j]) / bnorm <= tol ) + break; } - - /* update x = x_0 + Vy */ - Vector_MakeZero( workspace->p, N ); - for( i = 0; i < j; i++ ) - Vector_Add( workspace->p, workspace->y[i], workspace->v[i], N ); - //Backward_Subs( U, workspace->p, workspace->p ); - //Forward_Subs( L, workspace->p, workspace->p ); - Vector_Add( x, 1., workspace->p, N ); - - /* stopping condition */ - if( fabs(workspace->g[j]) / bnorm <= tol ) - break; - } - - // Sparse_MatVec( H, x, workspace->b_prm ); - // for( i = 0; i < N; ++i ) - // workspace->b_prm[i] *= workspace->Hdia_inv[i]; - // fprintf( fout, "\n%10s%15s%15s\n", "b_prc", "b_prm", "x" ); - // for( i = 0; i < N; ++i ) - // fprintf( fout, "%10.5f%15.12f%15.12f\n", - // workspace->b_prc[i], workspace->b_prm[i], x[i] );*/ - - // fprintf(fout,"GMRES outer:%d, inner:%d iters - residual norm: %25.20f\n", - // itr, j, fabs( workspace->g[j] ) / bnorm ); - // data->timing.matvec += itr * RESTART + j; - - Deallocate_Matrix( Dinv_U ); - Deallocate_Matrix( Dinv_L ); - - if( itr >= MAX_ITR ) - { - fprintf( stderr, "GMRES convergence failed\n" ); - // return -1; - return itr * (RESTART+1) + j + 1; - } - - return itr * (RESTART+1) + j + 1; + + // Sparse_MatVec( H, x, workspace->b_prm ); + // for( i = 0; i < N; ++i ) + // workspace->b_prm[i] *= workspace->Hdia_inv[i]; + // fprintf( fout, "\n%10s%15s%15s\n", "b_prc", "b_prm", "x" ); + // for( i = 0; i < N; ++i ) + // fprintf( fout, "%10.5f%15.12f%15.12f\n", + // workspace->b_prc[i], workspace->b_prm[i], x[i] );*/ + + // fprintf(fout,"GMRES outer:%d, inner:%d iters - residual norm: %25.20f\n", + // itr, j, fabs( workspace->g[j] ) / bnorm ); + // data->timing.matvec += itr * RESTART + j; + + Deallocate_Matrix( Dinv_U ); + Deallocate_Matrix( Dinv_L ); + + if ( itr >= MAX_ITR ) + { + fprintf( stderr, "GMRES convergence failed\n" ); + // return -1; + return itr * (RESTART + 1) + j + 1; + } + + return itr * (RESTART + 1) + j + 1; } -int PCG( static_storage *workspace, sparse_matrix *A, real *b, real tol, - sparse_matrix *L, sparse_matrix *U, real *x, FILE *fout ) +int PCG( static_storage *workspace, sparse_matrix *A, real *b, real tol, + sparse_matrix *L, sparse_matrix *U, real *x, FILE *fout ) { - int i, N; - real tmp, alpha, beta, b_norm, r_norm; - real sig0, sig_old, sig_new; - - N = A->n; - b_norm = Norm( b, N ); - //fprintf( stderr, "b_norm: %.15e\n", b_norm ); - - Sparse_MatVec( A, x, workspace->q ); - Vector_Sum( workspace->r , 1., b, -1., workspace->q, N ); - r_norm = Norm(workspace->r, N); - //Print_Soln( workspace, x, q, b, N ); - //fprintf( stderr, "res: %.15e\n", r_norm ); - - Forward_Subs( L, workspace->r, workspace->d ); - Backward_Subs( U, workspace->d, workspace->p ); - sig_new = Dot( workspace->r, workspace->p, N ); - sig0 = sig_new; - - for( i = 0; i < 200 && r_norm/b_norm > tol; ++i ) { - //for( i = 0; i < 200 && sig_new > SQR(tol) * sig0; ++i ) { - Sparse_MatVec( A, workspace->p, workspace->q ); - tmp = Dot( workspace->q, workspace->p, N ); - alpha = sig_new / tmp; - Vector_Add( x, alpha, workspace->p, N ); - //fprintf( stderr, "iter%d: |p|=%.15e |q|=%.15e tmp=%.15e\n", - // i+1, Norm(workspace->p,N), Norm(workspace->q,N), tmp ); - - Vector_Add( workspace->r, -alpha, workspace->q, N ); + int i, N; + real tmp, alpha, beta, b_norm, r_norm; + real sig0, sig_old, sig_new; + + N = A->n; + b_norm = Norm( b, N ); + //fprintf( stderr, "b_norm: %.15e\n", b_norm ); + + Sparse_MatVec( A, x, workspace->q ); + Vector_Sum( workspace->r , 1., b, -1., workspace->q, N ); r_norm = Norm(workspace->r, N); + //Print_Soln( workspace, x, q, b, N ); //fprintf( stderr, "res: %.15e\n", r_norm ); - + Forward_Subs( L, workspace->r, workspace->d ); - Backward_Subs( U, workspace->d, workspace->d ); - sig_old = sig_new; - sig_new = Dot( workspace->r, workspace->d, N ); - beta = sig_new / sig_old; - Vector_Sum( workspace->p, 1., workspace->d, beta, workspace->p, N ); - } - - //fprintf( fout, "CG took %d iterations\n", i ); - if( i >= 200 ) { - fprintf( stderr, "CG convergence failed!\n" ); + Backward_Subs( U, workspace->d, workspace->p ); + sig_new = Dot( workspace->r, workspace->p, N ); + sig0 = sig_new; + + for ( i = 0; i < 200 && r_norm / b_norm > tol; ++i ) + { + //for( i = 0; i < 200 && sig_new > SQR(tol) * sig0; ++i ) { + Sparse_MatVec( A, workspace->p, workspace->q ); + tmp = Dot( workspace->q, workspace->p, N ); + alpha = sig_new / tmp; + Vector_Add( x, alpha, workspace->p, N ); + //fprintf( stderr, "iter%d: |p|=%.15e |q|=%.15e tmp=%.15e\n", + // i+1, Norm(workspace->p,N), Norm(workspace->q,N), tmp ); + + Vector_Add( workspace->r, -alpha, workspace->q, N ); + r_norm = Norm(workspace->r, N); + //fprintf( stderr, "res: %.15e\n", r_norm ); + + Forward_Subs( L, workspace->r, workspace->d ); + Backward_Subs( U, workspace->d, workspace->d ); + sig_old = sig_new; + sig_new = Dot( workspace->r, workspace->d, N ); + beta = sig_new / sig_old; + Vector_Sum( workspace->p, 1., workspace->d, beta, workspace->p, N ); + } + + //fprintf( fout, "CG took %d iterations\n", i ); + if ( i >= 200 ) + { + fprintf( stderr, "CG convergence failed!\n" ); + return i; + } + return i; - } - - return i; } -int CG( static_storage *workspace, sparse_matrix *H, - real *b, real tol, real *x, FILE *fout ) +int CG( static_storage *workspace, sparse_matrix *H, + real *b, real tol, real *x, FILE *fout ) { - int i, j, N; - real tmp, alpha, beta, b_norm; - real sig_old, sig_new, sig0; - - N = H->n; - b_norm = Norm( b, N ); - //fprintf( stderr, "b_norm: %10.6f\n", b_norm ); - - Sparse_MatVec( H, x, workspace->q ); - Vector_Sum( workspace->r , 1., b, -1., workspace->q, N ); - for( j = 0; j < N; ++j ) - workspace->d[j] = workspace->r[j] * workspace->Hdia_inv[j]; - - sig_new = Dot( workspace->r, workspace->d, N ); - sig0 = sig_new; - //Print_Soln( workspace, x, q, b, N ); - //fprintf( stderr, "sig_new: %24.15e, d_norm:%24.15e, q_norm:%24.15e\n", - // sqrt(sig_new), Norm(workspace->d,N), Norm(workspace->q,N) ); - //fprintf( stderr, "sig_new: %f\n", sig_new ); - - for( i = 0; i < 300 && SQRT(sig_new) / b_norm > tol; ++i ) { - //for( i = 0; i < 300 && sig_new > SQR(tol)*sig0; ++i ) { - Sparse_MatVec( H, workspace->d, workspace->q ); - tmp = Dot( workspace->d, workspace->q, N ); - //fprintf( stderr, "tmp: %f\n", tmp ); - alpha = sig_new / tmp; - Vector_Add( x, alpha, workspace->d, N ); - //fprintf( stderr, "d_norm:%24.15e, q_norm:%24.15e, tmp:%24.15e\n", - // Norm(workspace->d,N), Norm(workspace->q,N), tmp ); - - Vector_Add( workspace->r, -alpha, workspace->q, N ); - for( j = 0; j < N; ++j ) - workspace->p[j] = workspace->r[j] * workspace->Hdia_inv[j]; - - sig_old = sig_new; - sig_new = Dot( workspace->r, workspace->p, N ); - beta = sig_new / sig_old; - Vector_Sum( workspace->d, 1., workspace->p, beta, workspace->d, N ); + int i, j, N; + real tmp, alpha, beta, b_norm; + real sig_old, sig_new, sig0; + + N = H->n; + b_norm = Norm( b, N ); + //fprintf( stderr, "b_norm: %10.6f\n", b_norm ); + + Sparse_MatVec( H, x, workspace->q ); + Vector_Sum( workspace->r , 1., b, -1., workspace->q, N ); + for ( j = 0; j < N; ++j ) + workspace->d[j] = workspace->r[j] * workspace->Hdia_inv[j]; + + sig_new = Dot( workspace->r, workspace->d, N ); + sig0 = sig_new; + //Print_Soln( workspace, x, q, b, N ); + //fprintf( stderr, "sig_new: %24.15e, d_norm:%24.15e, q_norm:%24.15e\n", + // sqrt(sig_new), Norm(workspace->d,N), Norm(workspace->q,N) ); //fprintf( stderr, "sig_new: %f\n", sig_new ); - } - - fprintf( stderr, "CG took %d iterations\n", i ); - - if( i >= 300 ) { - fprintf( stderr, "CG convergence failed!\n" ); - return i; - } - return i; + for ( i = 0; i < 300 && SQRT(sig_new) / b_norm > tol; ++i ) + { + //for( i = 0; i < 300 && sig_new > SQR(tol)*sig0; ++i ) { + Sparse_MatVec( H, workspace->d, workspace->q ); + tmp = Dot( workspace->d, workspace->q, N ); + //fprintf( stderr, "tmp: %f\n", tmp ); + alpha = sig_new / tmp; + Vector_Add( x, alpha, workspace->d, N ); + //fprintf( stderr, "d_norm:%24.15e, q_norm:%24.15e, tmp:%24.15e\n", + // Norm(workspace->d,N), Norm(workspace->q,N), tmp ); + + Vector_Add( workspace->r, -alpha, workspace->q, N ); + for ( j = 0; j < N; ++j ) + workspace->p[j] = workspace->r[j] * workspace->Hdia_inv[j]; + + sig_old = sig_new; + sig_new = Dot( workspace->r, workspace->p, N ); + beta = sig_new / sig_old; + Vector_Sum( workspace->d, 1., workspace->p, beta, workspace->d, N ); + //fprintf( stderr, "sig_new: %f\n", sig_new ); + } + + fprintf( stderr, "CG took %d iterations\n", i ); + + if ( i >= 300 ) + { + fprintf( stderr, "CG convergence failed!\n" ); + return i; + } + + return i; } /* Steepest Descent */ -int SDM( static_storage *workspace, sparse_matrix *H, - real *b, real tol, real *x, FILE *fout ) +int SDM( static_storage *workspace, sparse_matrix *H, + real *b, real tol, real *x, FILE *fout ) { - int i, j, N; - real tmp, alpha, beta, b_norm; - real sig0, sig; - - N = H->n; - b_norm = Norm( b, N ); - //fprintf( stderr, "b_norm: %10.6f\n", b_norm ); - - Sparse_MatVec( H, x, workspace->q ); - Vector_Sum( workspace->r , 1., b, -1., workspace->q, N ); - for( j = 0; j < N; ++j ) - workspace->d[j] = workspace->r[j] * workspace->Hdia_inv[j]; - - sig = Dot( workspace->r, workspace->d, N ); - sig0 = sig; - - for( i = 0; i < 300 && SQRT(sig) / b_norm > tol; ++i ) { - Sparse_MatVec( H, workspace->d, workspace->q ); - - sig = Dot( workspace->r, workspace->d, N ); - tmp = Dot( workspace->d, workspace->q, N ); - alpha = sig / tmp; - - Vector_Add( x, alpha, workspace->d, N ); - Vector_Add( workspace->r, -alpha, workspace->q, N ); - for( j = 0; j < N; ++j ) - workspace->d[j] = workspace->r[j] * workspace->Hdia_inv[j]; - - //fprintf( stderr, "d_norm:%24.15e, q_norm:%24.15e, tmp:%24.15e\n", - // Norm(workspace->d,N), Norm(workspace->q,N), tmp ); - } - - fprintf( stderr, "SDM took %d iterations\n", i ); - - if( i >= 300 ) { - fprintf( stderr, "SDM convergence failed!\n" ); - return i; - } - - return i; -} + int i, j, N; + real tmp, alpha, beta, b_norm; + real sig0, sig; + N = H->n; + b_norm = Norm( b, N ); + //fprintf( stderr, "b_norm: %10.6f\n", b_norm ); + + Sparse_MatVec( H, x, workspace->q ); + Vector_Sum( workspace->r , 1., b, -1., workspace->q, N ); + for ( j = 0; j < N; ++j ) + workspace->d[j] = workspace->r[j] * workspace->Hdia_inv[j]; + + sig = Dot( workspace->r, workspace->d, N ); + sig0 = sig; + + for ( i = 0; i < 300 && SQRT(sig) / b_norm > tol; ++i ) + { + Sparse_MatVec( H, workspace->d, workspace->q ); + + sig = Dot( workspace->r, workspace->d, N ); + tmp = Dot( workspace->d, workspace->q, N ); + alpha = sig / tmp; + + Vector_Add( x, alpha, workspace->d, N ); + Vector_Add( workspace->r, -alpha, workspace->q, N ); + for ( j = 0; j < N; ++j ) + workspace->d[j] = workspace->r[j] * workspace->Hdia_inv[j]; + + //fprintf( stderr, "d_norm:%24.15e, q_norm:%24.15e, tmp:%24.15e\n", + // Norm(workspace->d,N), Norm(workspace->q,N), tmp ); + } + + fprintf( stderr, "SDM took %d iterations\n", i ); + + if ( i >= 300 ) + { + fprintf( stderr, "SDM convergence failed!\n" ); + return i; + } + + return i; +} diff --git a/puremd_rc_1003/sPuReMD/GMRES.h b/puremd_rc_1003/sPuReMD/GMRES.h index c5db381f..37aa994b 100644 --- a/puremd_rc_1003/sPuReMD/GMRES.h +++ b/puremd_rc_1003/sPuReMD/GMRES.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -28,29 +28,29 @@ typedef enum { - LOWER = 0, - UPPER = 1, + LOWER = 0, + UPPER = 1, } TRIANGULARITY; -int GMRES( static_storage*, sparse_matrix*, - real*, real, real*, FILE* ); +int GMRES( static_storage*, sparse_matrix*, + real*, real, real*, FILE* ); -int GMRES_HouseHolder( static_storage*, sparse_matrix*, - real*, real, real*, FILE* ); +int GMRES_HouseHolder( static_storage*, sparse_matrix*, + real*, real, real*, FILE* ); -int PGMRES( static_storage*, sparse_matrix*, real*, real, - sparse_matrix*, sparse_matrix*, real*, FILE* ); +int PGMRES( static_storage*, sparse_matrix*, real*, real, + sparse_matrix*, sparse_matrix*, real*, FILE* ); -int PGMRES_Jacobi( static_storage*, sparse_matrix*, real*, real, - sparse_matrix*, sparse_matrix*, real*, FILE* ); +int PGMRES_Jacobi( static_storage*, sparse_matrix*, real*, real, + sparse_matrix*, sparse_matrix*, real*, FILE* ); -int PCG( static_storage*, sparse_matrix*, real*, real, - sparse_matrix*, sparse_matrix*, real*, FILE* ); +int PCG( static_storage*, sparse_matrix*, real*, real, + sparse_matrix*, sparse_matrix*, real*, FILE* ); -int CG( static_storage*, sparse_matrix*, - real*, real, real*, FILE* ); +int CG( static_storage*, sparse_matrix*, + real*, real, real*, FILE* ); -int uyduruk_GMRES( static_storage*, sparse_matrix*, - real*, real, real*, int, FILE* ); +int uyduruk_GMRES( static_storage*, sparse_matrix*, + real*, real, real*, int, FILE* ); #endif diff --git a/puremd_rc_1003/sPuReMD/QEq.c b/puremd_rc_1003/sPuReMD/QEq.c index ad1c0cbc..6a445347 100644 --- a/puremd_rc_1003/sPuReMD/QEq.c +++ b/puremd_rc_1003/sPuReMD/QEq.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -27,357 +27,373 @@ int compare_matrix_entry(const void *v1, const void *v2) { - /* larger element has larger column index */ - return ((sparse_matrix_entry *)v1)->j - ((sparse_matrix_entry *)v2)->j; + /* larger element has larger column index */ + return ((sparse_matrix_entry *)v1)->j - ((sparse_matrix_entry *)v2)->j; } void Sort_Matrix_Rows( sparse_matrix *A ) { - int i, si, ei; - - /* sort each row of A using column indices */ - for( i = 0; i < A->n; ++i ) { - si = A->start[i]; - ei = A->start[i+1]; - /* polymorphic sort in standard C library */ - qsort( &(A->entries[si]), ei - si, - sizeof(sparse_matrix_entry), compare_matrix_entry ); - } + int i, si, ei; + + /* sort each row of A using column indices */ + for ( i = 0; i < A->n; ++i ) + { + si = A->start[i]; + ei = A->start[i + 1]; + /* polymorphic sort in standard C library */ + qsort( &(A->entries[si]), ei - si, + sizeof(sparse_matrix_entry), compare_matrix_entry ); + } } void Calculate_Droptol( sparse_matrix *A, real *droptol, real dtol ) { - int i, j, k; - real val; - - /* init droptol to 0 */ - for( i = 0; i < A->n; ++i ) - droptol[i] = 0; - - /* calculate sqaure of the norm of each row */ - for( i = 0; i < A->n; ++i ) { - for( k = A->start[i]; k < A->start[i+1]-1; ++k ) { - j = A->entries[k].j; - val = A->entries[k].val; - - droptol[i] += val*val; - droptol[j] += val*val; + int i, j, k; + real val; + + /* init droptol to 0 */ + for ( i = 0; i < A->n; ++i ) + droptol[i] = 0; + + /* calculate sqaure of the norm of each row */ + for ( i = 0; i < A->n; ++i ) + { + for ( k = A->start[i]; k < A->start[i + 1] - 1; ++k ) + { + j = A->entries[k].j; + val = A->entries[k].val; + + droptol[i] += val * val; + droptol[j] += val * val; + } + + val = A->entries[k].val; // diagonal entry + droptol[i] += val * val; } - - val = A->entries[k].val; // diagonal entry - droptol[i] += val*val; - } - - /* calculate local droptol for each row */ - //fprintf( stderr, "droptol: " ); - for( i = 0; i < A->n; ++i ) { - //fprintf( stderr, "%f-->", droptol[i] ); - droptol[i] = SQRT( droptol[i] ) * dtol; - //fprintf( stderr, "%f ", droptol[i] ); - } - //fprintf( stderr, "\n" ); + + /* calculate local droptol for each row */ + //fprintf( stderr, "droptol: " ); + for ( i = 0; i < A->n; ++i ) + { + //fprintf( stderr, "%f-->", droptol[i] ); + droptol[i] = SQRT( droptol[i] ) * dtol; + //fprintf( stderr, "%f ", droptol[i] ); + } + //fprintf( stderr, "\n" ); } int Estimate_LU_Fill( sparse_matrix *A, real *droptol ) { - int i, j, pj; - int fillin; - real val; - - fillin = 0; - - //fprintf( stderr, "n: %d\n", A->n ); - for( i = 0; i < A->n; ++i ) - for( pj = A->start[i]; pj < A->start[i+1]-1; ++pj ){ - j = A->entries[pj].j; - val = A->entries[pj].val; - //fprintf( stderr, "i: %d, j: %d", i, j ); - - if( fabs(val) > droptol[i] ) - ++fillin; - } + int i, j, pj; + int fillin; + real val; + + fillin = 0; + + //fprintf( stderr, "n: %d\n", A->n ); + for ( i = 0; i < A->n; ++i ) + for ( pj = A->start[i]; pj < A->start[i + 1] - 1; ++pj ) + { + j = A->entries[pj].j; + val = A->entries[pj].val; + //fprintf( stderr, "i: %d, j: %d", i, j ); - return fillin + A->n; + if ( fabs(val) > droptol[i] ) + ++fillin; + } + + return fillin + A->n; } /* Incomplete Cholesky factorization with thresholding */ -void ICHOLT( sparse_matrix *A, real *droptol, - sparse_matrix *L, sparse_matrix *U ) +void ICHOLT( sparse_matrix *A, real *droptol, + sparse_matrix *L, sparse_matrix *U ) { - sparse_matrix_entry tmp[1000]; - int i, j, pj, k1, k2, tmptop, Ltop; - real val; - int *Utop; - - Utop = (int*) malloc((A->n+1) * sizeof(int)); - - // clear variables - Ltop = 0; - tmptop = 0; - for( i = 0; i <= A->n; ++i ) - L->start[i] = U->start[i] = 0; - - for( i = 0; i < A->n; ++i ) - Utop[i] = 0; - - //fprintf( stderr, "n: %d\n", A->n ); - for( i = 0; i < A->n; ++i ){ - L->start[i] = Ltop; + sparse_matrix_entry tmp[1000]; + int i, j, pj, k1, k2, tmptop, Ltop; + real val; + int *Utop; + + Utop = (int*) malloc((A->n + 1) * sizeof(int)); + + // clear variables + Ltop = 0; tmptop = 0; + for ( i = 0; i <= A->n; ++i ) + L->start[i] = U->start[i] = 0; + + for ( i = 0; i < A->n; ++i ) + Utop[i] = 0; - for( pj = A->start[i]; pj < A->start[i+1]-1; ++pj ){ - j = A->entries[pj].j; - val = A->entries[pj].val; - //fprintf( stderr, "i: %d, j: %d", i, j ); - - if( fabs(val) > droptol[i] ){ - k1 = 0; - k2 = L->start[j]; - while( k1 < tmptop && k2 < L->start[j+1] ){ - if( tmp[k1].j < L->entries[k2].j ) - ++k1; - else if( tmp[k1].j > L->entries[k2].j ) - ++k2; - else - val -= (tmp[k1++].val * L->entries[k2++].val); - } - - // L matrix is lower triangular, - // so right before the start of next row comes jth diagonal - val /= L->entries[L->start[j+1]-1].val; - - tmp[tmptop].j = j; - tmp[tmptop].val = val; - ++tmptop; - } - //fprintf( stderr, " -- done\n" ); + //fprintf( stderr, "n: %d\n", A->n ); + for ( i = 0; i < A->n; ++i ) + { + L->start[i] = Ltop; + tmptop = 0; + + for ( pj = A->start[i]; pj < A->start[i + 1] - 1; ++pj ) + { + j = A->entries[pj].j; + val = A->entries[pj].val; + //fprintf( stderr, "i: %d, j: %d", i, j ); + + if ( fabs(val) > droptol[i] ) + { + k1 = 0; + k2 = L->start[j]; + while ( k1 < tmptop && k2 < L->start[j + 1] ) + { + if ( tmp[k1].j < L->entries[k2].j ) + ++k1; + else if ( tmp[k1].j > L->entries[k2].j ) + ++k2; + else + val -= (tmp[k1++].val * L->entries[k2++].val); + } + + // L matrix is lower triangular, + // so right before the start of next row comes jth diagonal + val /= L->entries[L->start[j + 1] - 1].val; + + tmp[tmptop].j = j; + tmp[tmptop].val = val; + ++tmptop; + } + //fprintf( stderr, " -- done\n" ); + } + + // compute the ith diagonal in L + // sanity check + if ( A->entries[pj].j != i ) + { + fprintf( stderr, "i=%d, badly built A matrix!\n", i ); + exit(999); + } + + val = A->entries[pj].val; + for ( k1 = 0; k1 < tmptop; ++k1 ) + val -= (tmp[k1].val * tmp[k1].val); + + tmp[tmptop].j = i; + tmp[tmptop].val = SQRT(val); + + // apply the dropping rule once again + //fprintf( stderr, "row%d: tmptop: %d\n", i, tmptop ); + //for( k1 = 0; k1<= tmptop; ++k1 ) + // fprintf( stderr, "%d(%f) ", tmp[k1].j, tmp[k1].val ); + //fprintf( stderr, "\n" ); + //fprintf( stderr, "row(%d): droptol=%.4f\n", i+1, droptol[i] ); + for ( k1 = 0; k1 < tmptop; ++k1 ) + if ( fabs(tmp[k1].val) > droptol[i] / tmp[tmptop].val ) + { + L->entries[Ltop].j = tmp[k1].j; + L->entries[Ltop].val = tmp[k1].val; + U->start[tmp[k1].j + 1]++; + ++Ltop; + //fprintf( stderr, "%d(%.4f) ", tmp[k1].j+1, tmp[k1].val ); + } + // keep the diagonal in any case + L->entries[Ltop].j = tmp[k1].j; + L->entries[Ltop].val = tmp[k1].val; + ++Ltop; + //fprintf( stderr, "%d(%.4f)\n", tmp[k1].j+1, tmp[k1].val ); } - - // compute the ith diagonal in L - // sanity check - if( A->entries[pj].j != i ) { - fprintf( stderr, "i=%d, badly built A matrix!\n", i ); - exit(999); + + L->start[i] = Ltop; + //fprintf( stderr, "nnz(L): %d, max: %d\n", Ltop, L->n * 50 ); + + /* U = L^T (Cholesky factorization) */ + for ( i = 1; i <= U->n; ++i ) + { + Utop[i] = U->start[i] = U->start[i] + U->start[i - 1] + 1; } - - val = A->entries[pj].val; - for( k1 = 0; k1 < tmptop; ++k1 ) - val -= (tmp[k1].val * tmp[k1].val); - - tmp[tmptop].j = i; - tmp[tmptop].val = SQRT(val); - - // apply the dropping rule once again - //fprintf( stderr, "row%d: tmptop: %d\n", i, tmptop ); - //for( k1 = 0; k1<= tmptop; ++k1 ) - // fprintf( stderr, "%d(%f) ", tmp[k1].j, tmp[k1].val ); - //fprintf( stderr, "\n" ); - //fprintf( stderr, "row(%d): droptol=%.4f\n", i+1, droptol[i] ); - for( k1 = 0; k1 < tmptop; ++k1 ) - if( fabs(tmp[k1].val) > droptol[i] / tmp[tmptop].val ){ - L->entries[Ltop].j = tmp[k1].j; - L->entries[Ltop].val = tmp[k1].val; - U->start[tmp[k1].j+1]++; - ++Ltop; - //fprintf( stderr, "%d(%.4f) ", tmp[k1].j+1, tmp[k1].val ); - } - // keep the diagonal in any case - L->entries[Ltop].j = tmp[k1].j; - L->entries[Ltop].val = tmp[k1].val; - ++Ltop; - //fprintf( stderr, "%d(%.4f)\n", tmp[k1].j+1, tmp[k1].val ); - } - - L->start[i] = Ltop; - //fprintf( stderr, "nnz(L): %d, max: %d\n", Ltop, L->n * 50 ); - - /* U = L^T (Cholesky factorization) */ - for( i = 1; i <= U->n; ++i ) - { - Utop[i] = U->start[i] = U->start[i] + U->start[i-1] + 1; - } - for( i = 0; i < L->n; ++i ) - { - for( pj = L->start[i]; pj < L->start[i+1]; ++pj ) + for ( i = 0; i < L->n; ++i ) { - j = L->entries[pj].j; - U->entries[Utop[j]].j = i; - U->entries[Utop[j]].val = L->entries[pj].val; - Utop[j]++; + for ( pj = L->start[i]; pj < L->start[i + 1]; ++pj ) + { + j = L->entries[pj].j; + U->entries[Utop[j]].j = i; + U->entries[Utop[j]].val = L->entries[pj].val; + Utop[j]++; + } } - } - //fprintf( stderr, "nnz(U): %d, max: %d\n", Utop[U->n], U->n * 50 ); + //fprintf( stderr, "nnz(U): %d, max: %d\n", Utop[U->n], U->n * 50 ); - free(Utop); + free(Utop); } -void Init_MatVec( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list *far_nbrs ) +void Init_MatVec( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list *far_nbrs ) { - int i, fillin; - real s_tmp, t_tmp; - //char fname[100]; - - if(control->refactor > 0 && - ((data->step-data->prev_steps)%control->refactor==0 || workspace->L==NULL)){ - //Print_Linear_System( system, control, workspace, data->step ); - Sort_Matrix_Rows( workspace->H ); - //fprintf( stderr, "H matrix sorted\n" ); - // TODO: comment out - Calculate_Droptol( workspace->H, workspace->droptol, control->droptol ); - //fprintf( stderr, "drop tolerances calculated\n" ); - if( workspace->L == NULL ) { - // TODO: ilu_par & ichol_par contain same sparsity pattern as H, - // so allocate with same NNZ (workspace->H->m) - fillin = Estimate_LU_Fill( workspace->H, workspace->droptol ); - if( Allocate_Matrix( &(workspace->L), far_nbrs->n, fillin ) == 0 || - Allocate_Matrix( &(workspace->U), far_nbrs->n, fillin ) == 0 ){ - fprintf( stderr, "not enough memory for LU matrices. terminating.\n" ); - exit(INSUFFICIENT_SPACE); - } + int i, fillin; + real s_tmp, t_tmp; + //char fname[100]; + + if (control->refactor > 0 && + ((data->step - data->prev_steps) % control->refactor == 0 || workspace->L == NULL)) + { + //Print_Linear_System( system, control, workspace, data->step ); + Sort_Matrix_Rows( workspace->H ); + //fprintf( stderr, "H matrix sorted\n" ); + // TODO: comment out + Calculate_Droptol( workspace->H, workspace->droptol, control->droptol ); + //fprintf( stderr, "drop tolerances calculated\n" ); + if ( workspace->L == NULL ) + { + // TODO: ilu_par & ichol_par contain same sparsity pattern as H, + // so allocate with same NNZ (workspace->H->m) + fillin = Estimate_LU_Fill( workspace->H, workspace->droptol ); + if ( Allocate_Matrix( &(workspace->L), far_nbrs->n, fillin ) == 0 || + Allocate_Matrix( &(workspace->U), far_nbrs->n, fillin ) == 0 ) + { + fprintf( stderr, "not enough memory for LU matrices. terminating.\n" ); + exit(INSUFFICIENT_SPACE); + } #if defined(DEBUG_FOCUS) - fprintf( stderr, "fillin = %d\n", fillin ); - fprintf( stderr, "allocated memory: L = U = %ldMB\n", - fillin * sizeof(sparse_matrix_entry) / (1024*1024) ); + fprintf( stderr, "fillin = %d\n", fillin ); + fprintf( stderr, "allocated memory: L = U = %ldMB\n", + fillin * sizeof(sparse_matrix_entry) / (1024 * 1024) ); #endif - } + } - // TODO: replace with ilu_par or ichol_par - // TODO: add parameters for sweeps to control file - //ICHOL_PAR( workspace->H, 3, workspace->L, workspace->U ); - ICHOLT( workspace->H, workspace->droptol, workspace->L, workspace->U ); + // TODO: replace with ilu_par or ichol_par + // TODO: add parameters for sweeps to control file + //ICHOL_PAR( workspace->H, 3, workspace->L, workspace->U ); + ICHOLT( workspace->H, workspace->droptol, workspace->L, workspace->U ); #if defined(DEBUG_FOCUS) - fprintf( stderr, "icholt-" ); - //sprintf( fname, "%s.L%d.out", control->sim_name, data->step ); - //Print_Sparse_Matrix2( workspace->L, fname ); - //Print_Sparse_Matrix( U ); + fprintf( stderr, "icholt-" ); + //sprintf( fname, "%s.L%d.out", control->sim_name, data->step ); + //Print_Sparse_Matrix2( workspace->L, fname ); + //Print_Sparse_Matrix( U ); #endif - } - - /* extrapolation for s & t */ - for( i = 0; i < system->N; ++i ) { - // no extrapolation - //s_tmp = workspace->s[0][i]; - //t_tmp = workspace->t[0][i]; - - // linear - //s_tmp = 2 * workspace->s[0][i] - workspace->s[1][i]; - //t_tmp = 2 * workspace->t[0][i] - workspace->t[1][i]; - - // quadratic - //s_tmp = workspace->s[2][i] + 3 * (workspace->s[0][i]-workspace->s[1][i]); - t_tmp = workspace->t[2][i] + 3*(workspace->t[0][i]-workspace->t[1][i]); - - // cubic - s_tmp = 4 * (workspace->s[0][i] + workspace->s[2][i]) - - (6 * workspace->s[1][i] + workspace->s[3][i] ); - //t_tmp = 4 * (workspace->t[0][i] + workspace->t[2][i]) - - // (6 * workspace->t[1][i] + workspace->t[3][i] ); - - // 4th order - //s_tmp = 5 * (workspace->s[0][i] - workspace->s[3][i]) + - // 10 * (-workspace->s[1][i] + workspace->s[2][i] ) + workspace->s[4][i]; - //t_tmp = 5 * (workspace->t[0][i] - workspace->t[3][i]) + - // 10 * (-workspace->t[1][i] + workspace->t[2][i] ) + workspace->t[4][i]; - - workspace->s[4][i] = workspace->s[3][i]; - workspace->s[3][i] = workspace->s[2][i]; - workspace->s[2][i] = workspace->s[1][i]; - workspace->s[1][i] = workspace->s[0][i]; - workspace->s[0][i] = s_tmp; - - workspace->t[4][i] = workspace->t[3][i]; - workspace->t[3][i] = workspace->t[2][i]; - workspace->t[2][i] = workspace->t[1][i]; - workspace->t[1][i] = workspace->t[0][i]; - workspace->t[0][i] = t_tmp; - } + } + + /* extrapolation for s & t */ + for ( i = 0; i < system->N; ++i ) + { + // no extrapolation + //s_tmp = workspace->s[0][i]; + //t_tmp = workspace->t[0][i]; + + // linear + //s_tmp = 2 * workspace->s[0][i] - workspace->s[1][i]; + //t_tmp = 2 * workspace->t[0][i] - workspace->t[1][i]; + + // quadratic + //s_tmp = workspace->s[2][i] + 3 * (workspace->s[0][i]-workspace->s[1][i]); + t_tmp = workspace->t[2][i] + 3 * (workspace->t[0][i] - workspace->t[1][i]); + + // cubic + s_tmp = 4 * (workspace->s[0][i] + workspace->s[2][i]) - + (6 * workspace->s[1][i] + workspace->s[3][i] ); + //t_tmp = 4 * (workspace->t[0][i] + workspace->t[2][i]) - + // (6 * workspace->t[1][i] + workspace->t[3][i] ); + + // 4th order + //s_tmp = 5 * (workspace->s[0][i] - workspace->s[3][i]) + + // 10 * (-workspace->s[1][i] + workspace->s[2][i] ) + workspace->s[4][i]; + //t_tmp = 5 * (workspace->t[0][i] - workspace->t[3][i]) + + // 10 * (-workspace->t[1][i] + workspace->t[2][i] ) + workspace->t[4][i]; + + workspace->s[4][i] = workspace->s[3][i]; + workspace->s[3][i] = workspace->s[2][i]; + workspace->s[2][i] = workspace->s[1][i]; + workspace->s[1][i] = workspace->s[0][i]; + workspace->s[0][i] = s_tmp; + + workspace->t[4][i] = workspace->t[3][i]; + workspace->t[3][i] = workspace->t[2][i]; + workspace->t[2][i] = workspace->t[1][i]; + workspace->t[1][i] = workspace->t[0][i]; + workspace->t[0][i] = t_tmp; + } } void Calculate_Charges( reax_system *system, static_storage *workspace ) { - int i; - real u, s_sum, t_sum; - - s_sum = t_sum = 0.; - for( i = 0; i < system->N; ++i ) { - s_sum += workspace->s[0][i]; - t_sum += workspace->t[0][i]; - } - - u = s_sum / t_sum; - for( i = 0; i < system->N; ++i ) - system->atoms[i].q = workspace->s[0][i] - u * workspace->t[0][i]; + int i; + real u, s_sum, t_sum; + + s_sum = t_sum = 0.; + for ( i = 0; i < system->N; ++i ) + { + s_sum += workspace->s[0][i]; + t_sum += workspace->t[0][i]; + } + + u = s_sum / t_sum; + for ( i = 0; i < system->N; ++i ) + system->atoms[i].q = workspace->s[0][i] - u * workspace->t[0][i]; } -void QEq( reax_system *system, control_params *control, simulation_data *data, - static_storage *workspace, list *far_nbrs, - output_controls *out_control ) +void QEq( reax_system *system, control_params *control, simulation_data *data, + static_storage *workspace, list *far_nbrs, + output_controls *out_control ) { - int matvecs; + int matvecs; - Init_MatVec( system, control, data, workspace, far_nbrs ); + Init_MatVec( system, control, data, workspace, far_nbrs ); - //if( data->step % 10 == 0 ) - // Print_Linear_System( system, control, workspace, far_nbrs, data->step ); + //if( data->step % 10 == 0 ) + // Print_Linear_System( system, control, workspace, far_nbrs, data->step ); - //TODO: add parameters in control file for solver choice and options -// matvecs = GMRES( workspace, workspace->H, + //TODO: add parameters in control file for solver choice and options +// matvecs = GMRES( workspace, workspace->H, // workspace->b_s, control->q_err, workspace->s[0], out_control->log ); -// matvecs += GMRES( workspace, workspace->H, +// matvecs += GMRES( workspace, workspace->H, // workspace->b_t, control->q_err, workspace->t[0], out_control->log ); - //matvecs = GMRES_HouseHolder( workspace, workspace->H, - // workspace->b_s, control->q_err, workspace->s[0], out_control->log ); - //matvecs += GMRES_HouseHolder( workspace, workspace->H, - // workspace->b_t, control->q_err, workspace->t[0], out_control->log ); - - //matvecs = PGMRES( workspace, workspace->H, workspace->b_s, control->q_err, - // workspace->L, workspace->U, workspace->s[0], out_control->log ); - //matvecs += PGMRES( workspace, workspace->H, workspace->b_t, control->q_err, - // workspace->L, workspace->U, workspace->t[0], out_control->log ); - - matvecs = PGMRES_Jacobi( workspace, workspace->H, workspace->b_s, control->q_err, - workspace->L, workspace->U, workspace->s[0], out_control->log ); - matvecs += PGMRES_Jacobi( workspace, workspace->H, workspace->b_t, control->q_err, - workspace->L, workspace->U, workspace->t[0], out_control->log ); - - //matvecs=PCG( workspace, workspace->H, workspace->b_s, control->q_err, - // workspace->L, workspace->U, workspace->s[0], out_control->log ) + 1; - ///matvecs+=PCG( workspace, workspace->H, workspace->b_t, control->q_err, - // workspace->L, workspace->U, workspace->t[0], out_control->log ) + 1; - - //matvecs = CG( workspace, workspace->H, - // workspace->b_s, control->q_err, workspace->s[0], out_control->log ) + 1; - //matvecs += CG( workspace, workspace->H, - // workspace->b_t, control->q_err, workspace->t[0], out_control->log ) + 1; - - //matvecs = SDM( workspace, workspace->H, - // workspace->b_s, control->q_err, workspace->s[0], out_control->log ) + 1; - //matvecs += SDM( workspace, workspace->H, - // workspace->b_t, control->q_err, workspace->t[0], out_control->log ) + 1; - - data->timing.matvecs += matvecs; + //matvecs = GMRES_HouseHolder( workspace, workspace->H, + // workspace->b_s, control->q_err, workspace->s[0], out_control->log ); + //matvecs += GMRES_HouseHolder( workspace, workspace->H, + // workspace->b_t, control->q_err, workspace->t[0], out_control->log ); + + //matvecs = PGMRES( workspace, workspace->H, workspace->b_s, control->q_err, + // workspace->L, workspace->U, workspace->s[0], out_control->log ); + //matvecs += PGMRES( workspace, workspace->H, workspace->b_t, control->q_err, + // workspace->L, workspace->U, workspace->t[0], out_control->log ); + + matvecs = PGMRES_Jacobi( workspace, workspace->H, workspace->b_s, control->q_err, + workspace->L, workspace->U, workspace->s[0], out_control->log ); + matvecs += PGMRES_Jacobi( workspace, workspace->H, workspace->b_t, control->q_err, + workspace->L, workspace->U, workspace->t[0], out_control->log ); + + //matvecs=PCG( workspace, workspace->H, workspace->b_s, control->q_err, + // workspace->L, workspace->U, workspace->s[0], out_control->log ) + 1; + ///matvecs+=PCG( workspace, workspace->H, workspace->b_t, control->q_err, + // workspace->L, workspace->U, workspace->t[0], out_control->log ) + 1; + + //matvecs = CG( workspace, workspace->H, + // workspace->b_s, control->q_err, workspace->s[0], out_control->log ) + 1; + //matvecs += CG( workspace, workspace->H, + // workspace->b_t, control->q_err, workspace->t[0], out_control->log ) + 1; + + //matvecs = SDM( workspace, workspace->H, + // workspace->b_s, control->q_err, workspace->s[0], out_control->log ) + 1; + //matvecs += SDM( workspace, workspace->H, + // workspace->b_t, control->q_err, workspace->t[0], out_control->log ) + 1; + + data->timing.matvecs += matvecs; #if defined(DEBUG_FOCUS) - fprintf( stderr, "linsolve-" ); + fprintf( stderr, "linsolve-" ); #endif - Calculate_Charges( system, workspace ); - //fprintf( stderr, "%d %.9f %.9f %.9f %.9f %.9f %.9f\n", - // data->step, - // workspace->s[0][0], workspace->t[0][0], - // workspace->s[0][1], workspace->t[0][1], - // workspace->s[0][2], workspace->t[0][2] ); - // if( data->step == control->nsteps ) - //Print_Charges( system, control, workspace, data->step ); + Calculate_Charges( system, workspace ); + //fprintf( stderr, "%d %.9f %.9f %.9f %.9f %.9f %.9f\n", + // data->step, + // workspace->s[0][0], workspace->t[0][0], + // workspace->s[0][1], workspace->t[0][1], + // workspace->s[0][2], workspace->t[0][2] ); + // if( data->step == control->nsteps ) + //Print_Charges( system, control, workspace, data->step ); } diff --git a/puremd_rc_1003/sPuReMD/QEq.h b/puremd_rc_1003/sPuReMD/QEq.h index f594d1ed..f598061b 100644 --- a/puremd_rc_1003/sPuReMD/QEq.h +++ b/puremd_rc_1003/sPuReMD/QEq.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -24,7 +24,7 @@ #include "mytypes.h" -void QEq( reax_system*, control_params*, simulation_data*, static_storage*, - list*, output_controls* ); +void QEq( reax_system*, control_params*, simulation_data*, static_storage*, + list*, output_controls* ); #endif diff --git a/puremd_rc_1003/sPuReMD/allocate.c b/puremd_rc_1003/sPuReMD/allocate.c index c9e8e1d9..56bacd6d 100644 --- a/puremd_rc_1003/sPuReMD/allocate.c +++ b/puremd_rc_1003/sPuReMD/allocate.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -24,267 +24,283 @@ void Reallocate_Neighbor_List( list *far_nbrs, int n, int num_intrs ) { - Delete_List( far_nbrs ); - if(!Make_List( n, num_intrs, TYP_FAR_NEIGHBOR, far_nbrs )){ - fprintf(stderr, "Problem in initializing far nbrs list. Terminating!\n"); - exit( INIT_ERR ); - } + Delete_List( far_nbrs ); + if (!Make_List( n, num_intrs, TYP_FAR_NEIGHBOR, far_nbrs )) + { + fprintf(stderr, "Problem in initializing far nbrs list. Terminating!\n"); + exit( INIT_ERR ); + } #if defined(DEBUG_FOCUS) - fprintf( stderr, "num_far = %d, far_nbrs = %d -> reallocating!\n", - num_intrs, far_nbrs->num_intrs ); - fprintf( stderr, "memory allocated: far_nbrs = %ldMB\n", - num_intrs * sizeof(far_neighbor_data) / (1024*1024) ); + fprintf( stderr, "num_far = %d, far_nbrs = %d -> reallocating!\n", + num_intrs, far_nbrs->num_intrs ); + fprintf( stderr, "memory allocated: far_nbrs = %ldMB\n", + num_intrs * sizeof(far_neighbor_data) / (1024 * 1024) ); #endif } int Allocate_Matrix( sparse_matrix **pH, int n, int m ) { - sparse_matrix *H; - - if( (*pH = (sparse_matrix*) malloc(sizeof(sparse_matrix))) == NULL ) - { - return 0; - } - - H = *pH; - H->n = n; - H->m = m; - if( (H->start = (int*) malloc(sizeof(int) * (n+1))) == NULL ) - { - return 0; - } - if( (H->entries = - (sparse_matrix_entry*) malloc(sizeof(sparse_matrix_entry)*m)) == NULL ) - { - return 0; - } + sparse_matrix *H; + + if ( (*pH = (sparse_matrix*) malloc(sizeof(sparse_matrix))) == NULL ) + { + return 0; + } + + H = *pH; + H->n = n; + H->m = m; + if ( (H->start = (int*) malloc(sizeof(int) * (n + 1))) == NULL ) + { + return 0; + } + if ( (H->entries = + (sparse_matrix_entry*) malloc(sizeof(sparse_matrix_entry) * m)) == NULL ) + { + return 0; + } // if( ((H->j = (int*) malloc(sizeof(int)*m)) == NULL) || // ((H->val = (real*) malloc(sizeof(real)*m)) == NULL) ) // { // return 0; // } - return 1; + return 1; } void Deallocate_Matrix( sparse_matrix *H ) { - free(H->start); - free(H->entries); - free(H); + free(H->start); + free(H->entries); + free(H); } int Reallocate_Matrix( sparse_matrix **H, int n, int m, char *name ) { - Deallocate_Matrix( *H ); - if( !Allocate_Matrix( H, n, m ) ) { - fprintf(stderr, "not enough space for %s matrix. terminating!\n", name); - exit( 1 ); - } + Deallocate_Matrix( *H ); + if ( !Allocate_Matrix( H, n, m ) ) + { + fprintf(stderr, "not enough space for %s matrix. terminating!\n", name); + exit( 1 ); + } #if defined(DEBUG_FOCUS) - fprintf( stderr, "reallocating %s matrix, n = %d, m = %d\n", - name, n, m ); - fprintf( stderr, "memory allocated: %s = %ldMB\n", - name, m * sizeof(sparse_matrix_entry) / (1024*1024) ); + fprintf( stderr, "reallocating %s matrix, n = %d, m = %d\n", + name, n, m ); + fprintf( stderr, "memory allocated: %s = %ldMB\n", + name, m * sizeof(sparse_matrix_entry) / (1024 * 1024) ); #endif - return 1; + return 1; } -int Allocate_HBond_List( int n, int num_h, int *h_index, int *hb_top, - list *hbonds ) +int Allocate_HBond_List( int n, int num_h, int *h_index, int *hb_top, + list *hbonds ) { - int i, num_hbonds; - - num_hbonds = 0; - /* find starting indexes for each H and the total number of hbonds */ - for( i = 1; i < n; ++i ) - hb_top[i] += hb_top[i-1]; - num_hbonds = hb_top[n-1]; - - if( !Make_List(num_h, num_hbonds, TYP_HBOND, hbonds ) ) { - fprintf( stderr, "not enough space for hbonds list. terminating!\n" ); - exit( INIT_ERR ); - } - - for( i = 0; i < n; ++i ) - if( h_index[i] == 0 ){ - Set_Start_Index( 0, 0, hbonds ); - Set_End_Index( 0, 0, hbonds ); + int i, num_hbonds; + + num_hbonds = 0; + /* find starting indexes for each H and the total number of hbonds */ + for ( i = 1; i < n; ++i ) + hb_top[i] += hb_top[i - 1]; + num_hbonds = hb_top[n - 1]; + + if ( !Make_List(num_h, num_hbonds, TYP_HBOND, hbonds ) ) + { + fprintf( stderr, "not enough space for hbonds list. terminating!\n" ); + exit( INIT_ERR ); } - else if( h_index[i] > 0 ){ - Set_Start_Index( h_index[i], hb_top[i-1], hbonds ); - Set_End_Index( h_index[i], hb_top[i-1], hbonds ); - } - + + for ( i = 0; i < n; ++i ) + if ( h_index[i] == 0 ) + { + Set_Start_Index( 0, 0, hbonds ); + Set_End_Index( 0, 0, hbonds ); + } + else if ( h_index[i] > 0 ) + { + Set_Start_Index( h_index[i], hb_top[i - 1], hbonds ); + Set_End_Index( h_index[i], hb_top[i - 1], hbonds ); + } + #if defined(DEBUG_FOCUS) - fprintf( stderr, "allocating hbonds - num_hbonds: %d\n", num_hbonds ); - fprintf( stderr, "memory allocated: hbonds = %ldMB\n", - num_hbonds * sizeof(hbond_data) / (1024*1024) ); + fprintf( stderr, "allocating hbonds - num_hbonds: %d\n", num_hbonds ); + fprintf( stderr, "memory allocated: hbonds = %ldMB\n", + num_hbonds * sizeof(hbond_data) / (1024 * 1024) ); #endif - return 1; + return 1; } int Reallocate_HBonds_List( int n, int num_h, int *h_index, list *hbonds ) { - int i; - int *hb_top; + int i; + int *hb_top; #if defined(DEBUG_FOCUS) - fprintf( stderr, "reallocating hbonds\n" ); + fprintf( stderr, "reallocating hbonds\n" ); #endif - hb_top = calloc( n, sizeof(int) ); - for( i = 0; i < n; ++i ) - if( h_index[i] >= 0 ) - hb_top[i] = MAX(Num_Entries(h_index[i],hbonds)*SAFE_HBONDS, MIN_HBONDS); - - Delete_List( hbonds ); - - Allocate_HBond_List( n, num_h, h_index, hb_top, hbonds ); - - free( hb_top ); - - return 1; + hb_top = calloc( n, sizeof(int) ); + for ( i = 0; i < n; ++i ) + if ( h_index[i] >= 0 ) + hb_top[i] = MAX(Num_Entries(h_index[i], hbonds) * SAFE_HBONDS, MIN_HBONDS); + + Delete_List( hbonds ); + + Allocate_HBond_List( n, num_h, h_index, hb_top, hbonds ); + + free( hb_top ); + + return 1; } int Allocate_Bond_List( int n, int *bond_top, list *bonds ) { - int i, num_bonds; - - num_bonds = 0; - /* find starting indexes for each atom and the total number of bonds */ - for( i = 1; i < n; ++i ) - bond_top[i] += bond_top[i-1]; - num_bonds = bond_top[n-1]; - - if( !Make_List(n, num_bonds, TYP_BOND, bonds ) ) { - fprintf( stderr, "not enough space for bonds list. terminating!\n" ); - exit( INIT_ERR ); - } - - Set_Start_Index( 0, 0, bonds ); - Set_End_Index( 0, 0, bonds ); - for( i = 1; i < n; ++i ) { - Set_Start_Index( i, bond_top[i-1], bonds ); - Set_End_Index( i, bond_top[i-1], bonds ); - } + int i, num_bonds; + + num_bonds = 0; + /* find starting indexes for each atom and the total number of bonds */ + for ( i = 1; i < n; ++i ) + bond_top[i] += bond_top[i - 1]; + num_bonds = bond_top[n - 1]; + + if ( !Make_List(n, num_bonds, TYP_BOND, bonds ) ) + { + fprintf( stderr, "not enough space for bonds list. terminating!\n" ); + exit( INIT_ERR ); + } + + Set_Start_Index( 0, 0, bonds ); + Set_End_Index( 0, 0, bonds ); + for ( i = 1; i < n; ++i ) + { + Set_Start_Index( i, bond_top[i - 1], bonds ); + Set_End_Index( i, bond_top[i - 1], bonds ); + } #if defined(DEBUG_FOCUS) - fprintf( stderr, "allocating bonds - num_bonds: %d\n", num_bonds ); - fprintf( stderr, "memory allocated: bonds = %ldMB\n", - num_bonds * sizeof(bond_data) / (1024*1024) ); + fprintf( stderr, "allocating bonds - num_bonds: %d\n", num_bonds ); + fprintf( stderr, "memory allocated: bonds = %ldMB\n", + num_bonds * sizeof(bond_data) / (1024 * 1024) ); #endif - return 1; + return 1; } int Reallocate_Bonds_List( int n, list *bonds, int *num_bonds, int *est_3body ) { - int i; - int *bond_top; + int i; + int *bond_top; #if defined(DEBUG_FOCUS) - fprintf( stderr, "reallocating bonds\n" ); + fprintf( stderr, "reallocating bonds\n" ); #endif - bond_top = calloc( n, sizeof(int) ); - *est_3body = 0; - for( i = 0; i < n; ++i ){ - *est_3body += SQR( Num_Entries( i, bonds ) ); - bond_top[i] = MAX( Num_Entries( i, bonds ) * 2, MIN_BONDS ); - } + bond_top = calloc( n, sizeof(int) ); + *est_3body = 0; + for ( i = 0; i < n; ++i ) + { + *est_3body += SQR( Num_Entries( i, bonds ) ); + bond_top[i] = MAX( Num_Entries( i, bonds ) * 2, MIN_BONDS ); + } + + Delete_List( bonds ); - Delete_List( bonds ); + Allocate_Bond_List( n, bond_top, bonds ); + *num_bonds = bond_top[n - 1]; - Allocate_Bond_List( n, bond_top, bonds ); - *num_bonds = bond_top[n-1]; - - free( bond_top ); + free( bond_top ); - return 1; + return 1; } -void Reallocate( reax_system *system, static_storage *workspace, list **lists, - int nbr_flag ) +void Reallocate( reax_system *system, static_storage *workspace, list **lists, + int nbr_flag ) { - int i, j, k; - int num_bonds, est_3body; - reallocate_data *realloc; - grid *g; - - realloc = &(workspace->realloc); - g = &(system->g); - - if( realloc->num_far > 0 && nbr_flag ) { - Reallocate_Neighbor_List( (*lists)+FAR_NBRS, - system->N, realloc->num_far * SAFE_ZONE ); - realloc->num_far = -1; - } - - if( realloc->Htop > 0 ){ - Reallocate_Matrix(&(workspace->H), system->N, realloc->Htop*SAFE_ZONE,"H"); - realloc->Htop = -1; - - Deallocate_Matrix( workspace->L ); - Deallocate_Matrix( workspace->U ); - workspace->L = NULL; - workspace->U = NULL; - } - - if( realloc->hbonds > 0 ){ - Reallocate_HBonds_List(system->N, workspace->num_H, 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 ); - realloc->bonds = -1; - realloc->num_3body = MAX( realloc->num_3body, est_3body ); - } - - if( realloc->num_3body > 0 ) { - Delete_List( (*lists)+THREE_BODIES ); - - if( num_bonds == -1 ) - num_bonds = ((*lists)+BONDS)->num_intrs; - realloc->num_3body *= SAFE_ZONE; - - if( !Make_List( num_bonds, realloc->num_3body, - TYP_THREE_BODY, (*lists)+THREE_BODIES ) ) { - fprintf( stderr, "Problem in initializing angles list. Terminating!\n" ); - exit( INIT_ERR ); + int i, j, k; + int num_bonds, est_3body; + reallocate_data *realloc; + grid *g; + + realloc = &(workspace->realloc); + g = &(system->g); + + if ( realloc->num_far > 0 && nbr_flag ) + { + Reallocate_Neighbor_List( (*lists) + FAR_NBRS, + system->N, realloc->num_far * SAFE_ZONE ); + realloc->num_far = -1; + } + + if ( realloc->Htop > 0 ) + { + Reallocate_Matrix(&(workspace->H), system->N, realloc->Htop * SAFE_ZONE, "H"); + realloc->Htop = -1; + + Deallocate_Matrix( workspace->L ); + Deallocate_Matrix( workspace->U ); + workspace->L = NULL; + workspace->U = NULL; + } + + if ( realloc->hbonds > 0 ) + { + Reallocate_HBonds_List(system->N, workspace->num_H, 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 ); + realloc->bonds = -1; + realloc->num_3body = MAX( realloc->num_3body, est_3body ); } - realloc->num_3body = -1; + + if ( realloc->num_3body > 0 ) + { + Delete_List( (*lists) + THREE_BODIES ); + + if ( num_bonds == -1 ) + num_bonds = ((*lists) + BONDS)->num_intrs; + realloc->num_3body *= SAFE_ZONE; + + if ( !Make_List( num_bonds, realloc->num_3body, + TYP_THREE_BODY, (*lists) + THREE_BODIES ) ) + { + fprintf( stderr, "Problem in initializing angles list. Terminating!\n" ); + exit( INIT_ERR ); + } + 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", - realloc->num_3body*sizeof(three_body_interaction_data)/ - (1024*1024) ); + 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", + realloc->num_3body * sizeof(three_body_interaction_data) / + (1024 * 1024) ); #endif - } + } - if( realloc->gcell_atoms > -1 ){ + if ( realloc->gcell_atoms > -1 ) + { #if defined(DEBUG_FOCUS) - fprintf(stderr, "reallocating gcell: g->max_atoms: %d\n", g->max_atoms); + fprintf(stderr, "reallocating gcell: g->max_atoms: %d\n", g->max_atoms); #endif - for( i = 0; i < g->ncell[0]; i++ ) - for( j = 0; j < g->ncell[1]; j++ ) - for( k = 0; k < g->ncell[2]; k++ ) { - // reallocate g->atoms - free( g->atoms[i][j][k] ); - g->atoms[i][j][k] = (int*) - calloc(workspace->realloc.gcell_atoms, sizeof(int)); - } - realloc->gcell_atoms = -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++ ) + { + // reallocate g->atoms + free( g->atoms[i][j][k] ); + g->atoms[i][j][k] = (int*) + calloc(workspace->realloc.gcell_atoms, sizeof(int)); + } + realloc->gcell_atoms = -1; + } } diff --git a/puremd_rc_1003/sPuReMD/allocate.h b/puremd_rc_1003/sPuReMD/allocate.h index c7f9bf15..2581b3ba 100644 --- a/puremd_rc_1003/sPuReMD/allocate.h +++ b/puremd_rc_1003/sPuReMD/allocate.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ diff --git a/puremd_rc_1003/sPuReMD/analyze.c b/puremd_rc_1003/sPuReMD/analyze.c index ac5cfe30..45af4c6b 100644 --- a/puremd_rc_1003/sPuReMD/analyze.c +++ b/puremd_rc_1003/sPuReMD/analyze.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -27,865 +27,924 @@ #define MAX_FRAGMENT_TYPES 100 // copy bond list into old bond list -void Copy_Bond_List( reax_system *system, control_params *control, - list **lists ) +void Copy_Bond_List( reax_system *system, control_params *control, + list **lists ) { - int i, j, top_old; - list *new_bonds = (*lists) + BONDS; - list *old_bonds = (*lists) + OLD_BONDS; - - for( top_old = 0, i = 0; i < system->N; ++i ) { - Set_Start_Index( i, top_old, old_bonds ); - - // fprintf( stdout, "%d: ", i ); - for( j = Start_Index( i, new_bonds ); j < End_Index( i, new_bonds ); ++j ) - if( new_bonds->select.bond_list[j].bo_data.BO >= control->bg_cut ) { - // fprintf( stderr, "%d ", new_bonds->select.bond_list[j].nbr ); - old_bonds->select.bond_list[ top_old ].nbr = - new_bonds->select.bond_list[j].nbr; - old_bonds->select.bond_list[ top_old ].bo_data.BO = - new_bonds->select.bond_list[j].bo_data.BO; - top_old++; - } - - Set_End_Index( i, top_old, old_bonds); - // fprintf( stderr, "--- s: %d, e: %d\n", - // Start_Index( i, old_bonds ), End_Index( i, old_bonds ) ); - } + int i, j, top_old; + list *new_bonds = (*lists) + BONDS; + list *old_bonds = (*lists) + OLD_BONDS; + + for ( top_old = 0, i = 0; i < system->N; ++i ) + { + Set_Start_Index( i, top_old, old_bonds ); + + // fprintf( stdout, "%d: ", i ); + for ( j = Start_Index( i, new_bonds ); j < End_Index( i, new_bonds ); ++j ) + if ( new_bonds->select.bond_list[j].bo_data.BO >= control->bg_cut ) + { + // fprintf( stderr, "%d ", new_bonds->select.bond_list[j].nbr ); + old_bonds->select.bond_list[ top_old ].nbr = + new_bonds->select.bond_list[j].nbr; + old_bonds->select.bond_list[ top_old ].bo_data.BO = + new_bonds->select.bond_list[j].bo_data.BO; + top_old++; + } + + Set_End_Index( i, top_old, old_bonds); + // fprintf( stderr, "--- s: %d, e: %d\n", + // Start_Index( i, old_bonds ), End_Index( i, old_bonds ) ); + } } // ASSUMPTION: Bond lists are sorted int Compare_Bond_Lists( int atom, control_params *control, list **lists ) { - int oldp, newp; - list *new_bonds = (*lists) + BONDS; - list *old_bonds = (*lists) + OLD_BONDS; - - /*fprintf( stdout, "\n%d\nold_bonds:", atom ); - for( oldp = Start_Index( atom, old_bonds ); - oldp < End_Index( atom, old_bonds ); ++oldp ) - if( old_bonds->select.bond_list[oldp].bo_data.BO >= control->bg_cut ) - fprintf( stdout, "%5d", old_bonds->select.bond_list[oldp].nbr ); - - fprintf( stdout, "\nnew_bonds:" ); - for( newp = Start_Index( atom, new_bonds ); - newp < End_Index( atom, new_bonds ); ++newp ) - if( new_bonds->select.bond_list[newp].bo_data.BO >= control->bg_cut ) - fprintf( stdout, "%5d", new_bonds->select.bond_list[newp].nbr );*/ - - - for( oldp = Start_Index( atom, old_bonds ), - newp = Start_Index( atom, new_bonds ); - oldp < End_Index(atom, old_bonds) || newp < End_Index(atom, new_bonds); - oldp = MIN( oldp + 1, End_Index( atom, old_bonds ) ), - newp = MIN( newp + 1, End_Index( atom, new_bonds ) ) ) { - while( oldp < End_Index( atom, old_bonds ) && - old_bonds->select.bond_list[oldp].bo_data.BO < control->bg_cut ) - ++oldp; - - while( newp < End_Index( atom, new_bonds ) && - new_bonds->select.bond_list[newp].bo_data.BO < control->bg_cut ) - ++newp; - - /*fprintf( fout, "%d, oldp: %d - %d, newp: %d - %d", - atom, oldp, old_bonds->select.bond_list[oldp].nbr, - newp, new_bonds->select.bond_list[newp].nbr );*/ - - if( oldp < End_Index( atom, old_bonds ) ) { - /* there are some other bonds in the old list */ - if( newp < End_Index( atom, new_bonds ) ) { - if( old_bonds->select.bond_list[oldp].nbr != - new_bonds->select.bond_list[newp].nbr ) { - //fprintf( fout, " --> case1, return 1\n" ); - return 1; - } - } - else { - /* there is no other bond in the new list */ - //fprintf( fout, " --> case2, return 1\n" ); - return 1; - } - } - else { - /* there are no more bonds in old_bond list */ - if( newp < End_Index( atom, new_bonds ) ) { - /* there is at least one other bond in the new list */ - //fprintf( fout, " --> case 3, return 1\n" ); - return 1; - } - else { - /* there is no other bond in the new list, either */ - //fprintf( fout, " --> case 4, return 0\n" ); - return 0; - } + int oldp, newp; + list *new_bonds = (*lists) + BONDS; + list *old_bonds = (*lists) + OLD_BONDS; + + /*fprintf( stdout, "\n%d\nold_bonds:", atom ); + for( oldp = Start_Index( atom, old_bonds ); + oldp < End_Index( atom, old_bonds ); ++oldp ) + if( old_bonds->select.bond_list[oldp].bo_data.BO >= control->bg_cut ) + fprintf( stdout, "%5d", old_bonds->select.bond_list[oldp].nbr ); + + fprintf( stdout, "\nnew_bonds:" ); + for( newp = Start_Index( atom, new_bonds ); + newp < End_Index( atom, new_bonds ); ++newp ) + if( new_bonds->select.bond_list[newp].bo_data.BO >= control->bg_cut ) + fprintf( stdout, "%5d", new_bonds->select.bond_list[newp].nbr );*/ + + + for ( oldp = Start_Index( atom, old_bonds ), + newp = Start_Index( atom, new_bonds ); + oldp < End_Index(atom, old_bonds) || newp < End_Index(atom, new_bonds); + oldp = MIN( oldp + 1, End_Index( atom, old_bonds ) ), + newp = MIN( newp + 1, End_Index( atom, new_bonds ) ) ) + { + while ( oldp < End_Index( atom, old_bonds ) && + old_bonds->select.bond_list[oldp].bo_data.BO < control->bg_cut ) + ++oldp; + + while ( newp < End_Index( atom, new_bonds ) && + new_bonds->select.bond_list[newp].bo_data.BO < control->bg_cut ) + ++newp; + + /*fprintf( fout, "%d, oldp: %d - %d, newp: %d - %d", + atom, oldp, old_bonds->select.bond_list[oldp].nbr, + newp, new_bonds->select.bond_list[newp].nbr );*/ + + if ( oldp < End_Index( atom, old_bonds ) ) + { + /* there are some other bonds in the old list */ + if ( newp < End_Index( atom, new_bonds ) ) + { + if ( old_bonds->select.bond_list[oldp].nbr != + new_bonds->select.bond_list[newp].nbr ) + { + //fprintf( fout, " --> case1, return 1\n" ); + return 1; + } + } + else + { + /* there is no other bond in the new list */ + //fprintf( fout, " --> case2, return 1\n" ); + return 1; + } + } + else + { + /* there are no more bonds in old_bond list */ + if ( newp < End_Index( atom, new_bonds ) ) + { + /* there is at least one other bond in the new list */ + //fprintf( fout, " --> case 3, return 1\n" ); + return 1; + } + else + { + /* there is no other bond in the new list, either */ + //fprintf( fout, " --> case 4, return 0\n" ); + return 0; + } + } } - } - - return 0; + + return 0; } -void Get_Molecule( int atom, molecule *m, int *mark, reax_system *system, - control_params *control, list *bonds, int print, - FILE *fout ) +void Get_Molecule( int atom, molecule *m, int *mark, reax_system *system, + control_params *control, list *bonds, int print, + FILE *fout ) { - int i, start, end; - - start = Start_Index( atom, bonds ); - end = End_Index( atom, bonds ); - - if( print ) - fprintf( fout, "%5d(%2s)", - atom+1, system->reaxprm.sbp[ system->atoms[atom].type ].name ); - mark[atom] = 1; - m->atom_list[ m->atom_count++ ] = atom; - m->mtypes[ system->atoms[ atom ].type ]++; - - for( i = start; i < end; ++i ) - if( bonds->select.bond_list[i].bo_data.BO >= control->bg_cut && - !mark[bonds->select.bond_list[i].nbr] ) - Get_Molecule( bonds->select.bond_list[i].nbr, m, mark, - system, control, bonds, print, fout ); + int i, start, end; + + start = Start_Index( atom, bonds ); + end = End_Index( atom, bonds ); + + if ( print ) + fprintf( fout, "%5d(%2s)", + atom + 1, system->reaxprm.sbp[ system->atoms[atom].type ].name ); + mark[atom] = 1; + m->atom_list[ m->atom_count++ ] = atom; + m->mtypes[ system->atoms[ atom ].type ]++; + + for ( i = start; i < end; ++i ) + if ( bonds->select.bond_list[i].bo_data.BO >= control->bg_cut && + !mark[bonds->select.bond_list[i].nbr] ) + Get_Molecule( bonds->select.bond_list[i].nbr, m, mark, + system, control, bonds, print, fout ); } void Print_Molecule( reax_system *system, molecule *m, int mode, char *s ) { - int j, atom; + int j, atom; - s[0] = 0; + s[0] = 0; - if( mode == 1 ) { - /* print molecule summary */ - for( j = 0; j < MAX_ATOM_TYPES; ++j ) - if( m->mtypes[j] ) - sprintf( s, "%s%s%d", s, system->reaxprm.sbp[j].name, m->mtypes[j] ); + if ( mode == 1 ) + { + /* print molecule summary */ + for ( j = 0; j < MAX_ATOM_TYPES; ++j ) + if ( m->mtypes[j] ) + sprintf( s, "%s%s%d", s, system->reaxprm.sbp[j].name, m->mtypes[j] ); } - else if( mode == 2 ) { - /* print molecule details */ - for( j = 0; j < m->atom_count; ++j ) { - atom = m->atom_list[j]; - sprintf( s, "%s%s(%d)", - s, system->reaxprm.sbp[ system->atoms[atom].type ].name, atom ); + else if ( mode == 2 ) + { + /* print molecule details */ + for ( j = 0; j < m->atom_count; ++j ) + { + atom = m->atom_list[j]; + sprintf( s, "%s%s(%d)", + s, system->reaxprm.sbp[ system->atoms[atom].type ].name, atom ); + } } - } } -void Analyze_Molecules( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, FILE *fout ) +void Analyze_Molecules( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, FILE *fout ) { - int atom, i, j, k, l, flag; - int *mark = workspace->mark; - int *old_mark = workspace->old_mark; - int num_old, num_new; - char s[MAX_MOLECULE_SIZE * 10]; - list *new_bonds = (*lists) + BONDS; - list *old_bonds = (*lists) + OLD_BONDS; - molecule old_molecules[20], new_molecules[20]; - - fprintf( fout, "molecular analysis @ %d\n", data->step ); - memset( mark, 0, system->N * sizeof(int) ); - memset( old_mark, 0, system->N * sizeof(int) ); - - /* compare new molecules to old molecules */ - for( atom = 0; atom < system->N; ++atom ) - if( !mark[atom] ) { - //fprintf( fout, "atom %d is being compared\n", atom ); - if( Compare_Bond_Lists( atom, control, lists ) ) { - /* old & new lists are different, print the old and new molecules */ - num_old = num_new = 0; - flag = 0; - i = k = 0; - memset( &old_molecules[0], 0, sizeof(molecule) *20 ); - memset( &new_molecules[0], 0, sizeof(molecule) *20 ); - - fprintf( fout, "get_old_mol: " ); - Get_Molecule( atom, &old_molecules[num_old++], old_mark, - system, control, old_bonds, 1, fout ); - fprintf( fout, "\nget_new_mol: " ); - Get_Molecule( atom, &new_molecules[num_new++], mark, - system, control, new_bonds, 1, fout ); - fprintf( fout, "\n" ); - - while( !flag ) { - flag = 1; - - for( ; i < num_old; ++i ) - for( j = 0; j < old_molecules[i].atom_count; ++j ) - if( !mark[old_molecules[i].atom_list[j]] ) { - fprintf( fout, "get_new_mol: " ); - Get_Molecule( old_molecules[i].atom_list[j], - &new_molecules[num_new++], - mark, system, control, new_bonds, 1, fout ); - fprintf( fout, "\n" ); - flag = 0; - } - - for( ; k < num_new; ++k ) - for( l = 0; l < new_molecules[k].atom_count; ++l ) - if( !old_mark[new_molecules[k].atom_list[l]] ) { - fprintf( fout, "get_old_mol: " ); - Get_Molecule( new_molecules[k].atom_list[l], - &old_molecules[num_old++], - old_mark, system, control, old_bonds, 1, fout ); - fprintf( fout, "\n" ); - flag = 0; - } - } - - fprintf( fout, "old molecules: " ); - for( i = 0; i < num_old; ++i ) { - Print_Molecule( system, &old_molecules[i], 1, &s[0] ); - fprintf( fout, "%s\t", s ); - } - fprintf( fout, "\n" ); - - fprintf( fout, "new molecules: " ); - for( i = 0; i < num_new; ++i ) { - Print_Molecule( system, &new_molecules[i], 1, &s[0] ); - fprintf( fout, "%s\t", s ); - } - fprintf( fout, "\n" ); - } - } - - Copy_Bond_List( system, control, lists ); - - //free( mark ); - //free( old_mark ); - - fprintf( fout, "\n" ); - fflush( fout ); + int atom, i, j, k, l, flag; + int *mark = workspace->mark; + int *old_mark = workspace->old_mark; + int num_old, num_new; + char s[MAX_MOLECULE_SIZE * 10]; + list *new_bonds = (*lists) + BONDS; + list *old_bonds = (*lists) + OLD_BONDS; + molecule old_molecules[20], new_molecules[20]; + + fprintf( fout, "molecular analysis @ %d\n", data->step ); + memset( mark, 0, system->N * sizeof(int) ); + memset( old_mark, 0, system->N * sizeof(int) ); + + /* compare new molecules to old molecules */ + for ( atom = 0; atom < system->N; ++atom ) + if ( !mark[atom] ) + { + //fprintf( fout, "atom %d is being compared\n", atom ); + if ( Compare_Bond_Lists( atom, control, lists ) ) + { + /* old & new lists are different, print the old and new molecules */ + num_old = num_new = 0; + flag = 0; + i = k = 0; + memset( &old_molecules[0], 0, sizeof(molecule) * 20 ); + memset( &new_molecules[0], 0, sizeof(molecule) * 20 ); + + fprintf( fout, "get_old_mol: " ); + Get_Molecule( atom, &old_molecules[num_old++], old_mark, + system, control, old_bonds, 1, fout ); + fprintf( fout, "\nget_new_mol: " ); + Get_Molecule( atom, &new_molecules[num_new++], mark, + system, control, new_bonds, 1, fout ); + fprintf( fout, "\n" ); + + while ( !flag ) + { + flag = 1; + + for ( ; i < num_old; ++i ) + for ( j = 0; j < old_molecules[i].atom_count; ++j ) + if ( !mark[old_molecules[i].atom_list[j]] ) + { + fprintf( fout, "get_new_mol: " ); + Get_Molecule( old_molecules[i].atom_list[j], + &new_molecules[num_new++], + mark, system, control, new_bonds, 1, fout ); + fprintf( fout, "\n" ); + flag = 0; + } + + for ( ; k < num_new; ++k ) + for ( l = 0; l < new_molecules[k].atom_count; ++l ) + if ( !old_mark[new_molecules[k].atom_list[l]] ) + { + fprintf( fout, "get_old_mol: " ); + Get_Molecule( new_molecules[k].atom_list[l], + &old_molecules[num_old++], + old_mark, system, control, old_bonds, 1, fout ); + fprintf( fout, "\n" ); + flag = 0; + } + } + + fprintf( fout, "old molecules: " ); + for ( i = 0; i < num_old; ++i ) + { + Print_Molecule( system, &old_molecules[i], 1, &s[0] ); + fprintf( fout, "%s\t", s ); + } + fprintf( fout, "\n" ); + + fprintf( fout, "new molecules: " ); + for ( i = 0; i < num_new; ++i ) + { + Print_Molecule( system, &new_molecules[i], 1, &s[0] ); + fprintf( fout, "%s\t", s ); + } + fprintf( fout, "\n" ); + } + } + + Copy_Bond_List( system, control, lists ); + + //free( mark ); + //free( old_mark ); + + fprintf( fout, "\n" ); + fflush( fout ); } -void Report_Bond_Change( reax_system *system, control_params *control, - static_storage *workspace, list *old_bonds, - list *new_bonds, int a1, int a2, int flag, - FILE *fout ) +void Report_Bond_Change( reax_system *system, control_params *control, + static_storage *workspace, list *old_bonds, + list *new_bonds, int a1, int a2, int flag, + FILE *fout ) { - int i; - int rev1, rev2; - int mol1 = -1, mol2 = -1; - // which molecule the atom belongs to, 0: Silica, 1: Water - - rev1 = workspace->orig_id[a1]; - rev2 = workspace->orig_id[a2]; - - if( !strcmp( system->atoms[a1].name, " Si" ) || - !strcmp( system->atoms[a1].name, " O" ) ) - mol1 = 0; - else mol1 = 1; - - if( !strcmp( system->atoms[a2].name, " Si" ) || - !strcmp( system->atoms[a2].name, " O" ) ) - mol2 = 0; - else mol2 = 1; - - - if( mol1 == 0 && mol2 == 0 ) { // silica-silica - if( flag ) - fprintf( fout, "silica bond formation:" ); - else fprintf( fout, "silica bond breakage :" ); - - fprintf( fout, "%5d(%s)-%5d(%s)\n", - rev1, system->atoms[a1].name, rev2, system->atoms[a2].name ); - } - else if( mol1 == 1 && mol2 == 1 ) { // water-water - if( flag ) - fprintf( fout, "water bond formation:" ); - else fprintf( fout, "water bond breakage :" ); - - fprintf( fout, "%5d(%s)-%5d(%s)\n", - rev1, system->atoms[a1].name, rev2, system->atoms[a2].name ); - } - else { // water-silica! - if( flag ) - fprintf( fout, "SILICA-WATER bond formation:" ); - else fprintf( fout, "SILICA-WATER bond breakage :" ); - - fprintf( fout, "%5d(%s)-%5d(%s)\n", - rev1, system->atoms[a1].name, rev2, system->atoms[a2].name ); - - fprintf( fout, "%5d(%s) was connected to:", rev1, system->atoms[a1].name ); - for( i = Start_Index(a1, old_bonds); i < End_Index(a1, old_bonds); ++i ) - if( old_bonds->select.bond_list[i].bo_data.BO >= control->bg_cut ) - fprintf( fout, " %5d(%s)", - workspace->orig_id[ old_bonds->select.bond_list[i].nbr ], - system->atoms[ old_bonds->select.bond_list[i].nbr ].name ); - fprintf( fout, "\n" ); - - fprintf( fout, "%5d(%s) was connected to:", rev2, system->atoms[a2].name ); - for( i = Start_Index(a2, old_bonds); i < End_Index(a2, old_bonds); ++i ) - if( old_bonds->select.bond_list[i].bo_data.BO >= control->bg_cut ) - fprintf( fout, " %5d(%s)", - workspace->orig_id[ old_bonds->select.bond_list[i].nbr ], - system->atoms[ old_bonds->select.bond_list[i].nbr ].name ); - fprintf( fout, "\n" ); - } + int i; + int rev1, rev2; + int mol1 = -1, mol2 = -1; + // which molecule the atom belongs to, 0: Silica, 1: Water + + rev1 = workspace->orig_id[a1]; + rev2 = workspace->orig_id[a2]; + + if ( !strcmp( system->atoms[a1].name, " Si" ) || + !strcmp( system->atoms[a1].name, " O" ) ) + mol1 = 0; + else mol1 = 1; + + if ( !strcmp( system->atoms[a2].name, " Si" ) || + !strcmp( system->atoms[a2].name, " O" ) ) + mol2 = 0; + else mol2 = 1; + + + if ( mol1 == 0 && mol2 == 0 ) // silica-silica + { + if ( flag ) + fprintf( fout, "silica bond formation:" ); + else fprintf( fout, "silica bond breakage :" ); + + fprintf( fout, "%5d(%s)-%5d(%s)\n", + rev1, system->atoms[a1].name, rev2, system->atoms[a2].name ); + } + else if ( mol1 == 1 && mol2 == 1 ) // water-water + { + if ( flag ) + fprintf( fout, "water bond formation:" ); + else fprintf( fout, "water bond breakage :" ); + + fprintf( fout, "%5d(%s)-%5d(%s)\n", + rev1, system->atoms[a1].name, rev2, system->atoms[a2].name ); + } + else // water-silica! + { + if ( flag ) + fprintf( fout, "SILICA-WATER bond formation:" ); + else fprintf( fout, "SILICA-WATER bond breakage :" ); + + fprintf( fout, "%5d(%s)-%5d(%s)\n", + rev1, system->atoms[a1].name, rev2, system->atoms[a2].name ); + + fprintf( fout, "%5d(%s) was connected to:", rev1, system->atoms[a1].name ); + for ( i = Start_Index(a1, old_bonds); i < End_Index(a1, old_bonds); ++i ) + if ( old_bonds->select.bond_list[i].bo_data.BO >= control->bg_cut ) + fprintf( fout, " %5d(%s)", + workspace->orig_id[ old_bonds->select.bond_list[i].nbr ], + system->atoms[ old_bonds->select.bond_list[i].nbr ].name ); + fprintf( fout, "\n" ); + + fprintf( fout, "%5d(%s) was connected to:", rev2, system->atoms[a2].name ); + for ( i = Start_Index(a2, old_bonds); i < End_Index(a2, old_bonds); ++i ) + if ( old_bonds->select.bond_list[i].bo_data.BO >= control->bg_cut ) + fprintf( fout, " %5d(%s)", + workspace->orig_id[ old_bonds->select.bond_list[i].nbr ], + system->atoms[ old_bonds->select.bond_list[i].nbr ].name ); + fprintf( fout, "\n" ); + } } /* ASSUMPTION: Bond lists are sorted */ -void Compare_Bonding( int atom, reax_system *system, control_params *control, - static_storage *workspace, list *old_bonds, - list *new_bonds, FILE *fout ) +void Compare_Bonding( int atom, reax_system *system, control_params *control, + static_storage *workspace, list *old_bonds, + list *new_bonds, FILE *fout ) { - int oldp, newp; - - /* fprintf( fout, "\n%d\nold_bonds:", atom ); - for( oldp = Start_Index( atom, old_bonds ); - oldp < End_Index( atom, old_bonds ); ++oldp ) - if( old_bonds->select.bond_list[oldp].bo_data.BO >= control->bg_cut ) - fprintf( fout, "%5d", old_bonds->select.bond_list[oldp].nbr ); - - fprintf( fout, "\nnew_bonds:" ); - for( newp = Start_Index( atom, new_bonds ); - newp < End_Index( atom, new_bonds ); ++newp ) - if( new_bonds->select.bond_list[newp].bo_data.BO >= control->bg_cut ) - fprintf( fout, "%6d", new_bonds->select.bond_list[newp].nbr ); - fprintf( fout, "\n" ); */ - - for( oldp = Start_Index( atom, old_bonds ); - oldp < End_Index( atom, old_bonds ) && - old_bonds->select.bond_list[oldp].nbr < atom; - ++oldp ); - - for( newp = Start_Index( atom, new_bonds ); - newp < End_Index( atom, new_bonds ) && - new_bonds->select.bond_list[newp].nbr < atom; - ++newp ); - - while( oldp < End_Index( atom, old_bonds ) || - newp < End_Index( atom, new_bonds ) ) { - while( oldp < End_Index( atom, old_bonds ) && - old_bonds->select.bond_list[oldp].bo_data.BO < control->bg_cut ) - ++oldp; - - while( newp < End_Index( atom, new_bonds ) && - new_bonds->select.bond_list[newp].bo_data.BO < control->bg_cut ) - ++newp; - - /*fprintf( fout, "%d, oldp: %d - %d: %f newp: %d - %d: %f", - atom, oldp, old_bonds->select.bond_list[oldp].nbr, - old_bonds->select.bond_list[oldp].bo_data.BO, - newp, new_bonds->select.bond_list[newp].nbr, - new_bonds->select.bond_list[newp].bo_data.BO ); */ - - if( oldp < End_Index( atom, old_bonds ) ) { - /* there are some more bonds in the old list */ - if( newp < End_Index( atom, new_bonds ) ) { - if( old_bonds->select.bond_list[oldp].nbr < - new_bonds->select.bond_list[newp].nbr ) { - // fprintf( fout, "%5d-%5d bond broken\n", - // atom, old_bonds->select.bond_list[oldp].nbr ); - Report_Bond_Change( system, control, workspace, old_bonds, new_bonds, - atom, old_bonds->select.bond_list[oldp].nbr, 0, - fout ); - ++oldp; - } - else if( old_bonds->select.bond_list[oldp].nbr > - new_bonds->select.bond_list[newp].nbr ) { - // fprintf( fout, "%5d-%5d bond formed\n", - // atom, new_bonds->select.bond_list[newp].nbr ); - Report_Bond_Change( system, control, workspace, old_bonds, new_bonds, - atom, new_bonds->select.bond_list[newp].nbr, 1, - fout ); - ++newp; - } - else - ++newp, ++oldp; - } - else - /* there is no other bond in the new list */ - while( oldp < End_Index( atom, old_bonds ) ) { - if( old_bonds->select.bond_list[oldp].bo_data.BO>=control->bg_cut ) { - // fprintf( fout, "%5d-%5d bond broken\n", - // atom, old_bonds->select.bond_list[oldp].nbr ); - Report_Bond_Change( system, control, workspace, - old_bonds, new_bonds, atom, - old_bonds->select.bond_list[oldp].nbr, 0, - fout ); - } - ++oldp; - } - } - else { - /* there are no more bonds in old_bond list */ - if( newp < End_Index( atom, new_bonds ) ) - /* there is at least one other bond in the new list */ - while( newp < End_Index( atom, new_bonds ) ) { - if( new_bonds->select.bond_list[newp].bo_data.BO>=control->bg_cut ){ - // fprintf( fout, "%5d-%5d bond formed\n", - // atom, new_bonds->select.bond_list[newp].nbr ); - Report_Bond_Change( system, control, workspace, - old_bonds, new_bonds, atom, - new_bonds->select.bond_list[newp].nbr, 1, - fout ); - } - ++newp; - } - else { - /* there is no other bond in the new list, either -- - no need to do anything */ - } + int oldp, newp; + + /* fprintf( fout, "\n%d\nold_bonds:", atom ); + for( oldp = Start_Index( atom, old_bonds ); + oldp < End_Index( atom, old_bonds ); ++oldp ) + if( old_bonds->select.bond_list[oldp].bo_data.BO >= control->bg_cut ) + fprintf( fout, "%5d", old_bonds->select.bond_list[oldp].nbr ); + + fprintf( fout, "\nnew_bonds:" ); + for( newp = Start_Index( atom, new_bonds ); + newp < End_Index( atom, new_bonds ); ++newp ) + if( new_bonds->select.bond_list[newp].bo_data.BO >= control->bg_cut ) + fprintf( fout, "%6d", new_bonds->select.bond_list[newp].nbr ); + fprintf( fout, "\n" ); */ + + for ( oldp = Start_Index( atom, old_bonds ); + oldp < End_Index( atom, old_bonds ) && + old_bonds->select.bond_list[oldp].nbr < atom; + ++oldp ); + + for ( newp = Start_Index( atom, new_bonds ); + newp < End_Index( atom, new_bonds ) && + new_bonds->select.bond_list[newp].nbr < atom; + ++newp ); + + while ( oldp < End_Index( atom, old_bonds ) || + newp < End_Index( atom, new_bonds ) ) + { + while ( oldp < End_Index( atom, old_bonds ) && + old_bonds->select.bond_list[oldp].bo_data.BO < control->bg_cut ) + ++oldp; + + while ( newp < End_Index( atom, new_bonds ) && + new_bonds->select.bond_list[newp].bo_data.BO < control->bg_cut ) + ++newp; + + /*fprintf( fout, "%d, oldp: %d - %d: %f newp: %d - %d: %f", + atom, oldp, old_bonds->select.bond_list[oldp].nbr, + old_bonds->select.bond_list[oldp].bo_data.BO, + newp, new_bonds->select.bond_list[newp].nbr, + new_bonds->select.bond_list[newp].bo_data.BO ); */ + + if ( oldp < End_Index( atom, old_bonds ) ) + { + /* there are some more bonds in the old list */ + if ( newp < End_Index( atom, new_bonds ) ) + { + if ( old_bonds->select.bond_list[oldp].nbr < + new_bonds->select.bond_list[newp].nbr ) + { + // fprintf( fout, "%5d-%5d bond broken\n", + // atom, old_bonds->select.bond_list[oldp].nbr ); + Report_Bond_Change( system, control, workspace, old_bonds, new_bonds, + atom, old_bonds->select.bond_list[oldp].nbr, 0, + fout ); + ++oldp; + } + else if ( old_bonds->select.bond_list[oldp].nbr > + new_bonds->select.bond_list[newp].nbr ) + { + // fprintf( fout, "%5d-%5d bond formed\n", + // atom, new_bonds->select.bond_list[newp].nbr ); + Report_Bond_Change( system, control, workspace, old_bonds, new_bonds, + atom, new_bonds->select.bond_list[newp].nbr, 1, + fout ); + ++newp; + } + else + ++newp, ++oldp; + } + else + /* there is no other bond in the new list */ + while ( oldp < End_Index( atom, old_bonds ) ) + { + if ( old_bonds->select.bond_list[oldp].bo_data.BO >= control->bg_cut ) + { + // fprintf( fout, "%5d-%5d bond broken\n", + // atom, old_bonds->select.bond_list[oldp].nbr ); + Report_Bond_Change( system, control, workspace, + old_bonds, new_bonds, atom, + old_bonds->select.bond_list[oldp].nbr, 0, + fout ); + } + ++oldp; + } + } + else + { + /* there are no more bonds in old_bond list */ + if ( newp < End_Index( atom, new_bonds ) ) + /* there is at least one other bond in the new list */ + while ( newp < End_Index( atom, new_bonds ) ) + { + if ( new_bonds->select.bond_list[newp].bo_data.BO >= control->bg_cut ) + { + // fprintf( fout, "%5d-%5d bond formed\n", + // atom, new_bonds->select.bond_list[newp].nbr ); + Report_Bond_Change( system, control, workspace, + old_bonds, new_bonds, atom, + new_bonds->select.bond_list[newp].nbr, 1, + fout ); + } + ++newp; + } + else + { + /* there is no other bond in the new list, either -- + no need to do anything */ + } + } } - } } -void Visit_Bonds( int atom, int *mark, int *type, reax_system *system, - control_params *control, list *bonds, int ignore ) +void Visit_Bonds( int atom, int *mark, int *type, reax_system *system, + control_params *control, list *bonds, int ignore ) { - int i, t, start, end, nbr; - real bo; - - mark[atom] = 1; - t = system->atoms[atom].type; - if( ignore && control->ignore[t] ) - return; - type[t]++; - - start = Start_Index( atom, bonds ); - end = End_Index( atom, bonds ); - for( i = start; i < end; ++i ) { - nbr = bonds->select.bond_list[i].nbr; - bo = bonds->select.bond_list[i].bo_data.BO; - if( bo >= control->bg_cut && !mark[nbr] ) - Visit_Bonds( nbr, mark, type, system, control, bonds, ignore ); - } + int i, t, start, end, nbr; + real bo; + + mark[atom] = 1; + t = system->atoms[atom].type; + if ( ignore && control->ignore[t] ) + return; + type[t]++; + + start = Start_Index( atom, bonds ); + end = End_Index( atom, bonds ); + for ( i = start; i < end; ++i ) + { + nbr = bonds->select.bond_list[i].nbr; + bo = bonds->select.bond_list[i].bo_data.BO; + if ( bo >= control->bg_cut && !mark[nbr] ) + Visit_Bonds( nbr, mark, type, system, control, bonds, ignore ); + } } -void Analyze_Fragments( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, FILE *fout, int ignore ) +void Analyze_Fragments( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, FILE *fout, int ignore ) { - int atom, i, flag; - int *mark = workspace->mark; - int num_fragments, num_fragment_types; - char fragment[MAX_ATOM_TYPES]; - char fragments[MAX_FRAGMENT_TYPES][MAX_ATOM_TYPES]; - int fragment_count[MAX_FRAGMENT_TYPES]; - molecule m; - list *new_bonds = (*lists) + BONDS; - //list *old_bonds = (*lists) + OLD_BONDS; - - /* fragment analysis */ - fprintf( fout, "step%d fragments\n", data->step ); - num_fragments = 0; - num_fragment_types = 0; - memset( mark, 0, system->N * sizeof(int) ); - - for( atom = 0; atom < system->N; ++atom ) - if( !mark[atom] ) { - /* discover a new fragment */ - memset( m.mtypes, 0, MAX_ATOM_TYPES * sizeof(int) ); - Visit_Bonds( atom, mark, m.mtypes, system, control, new_bonds, ignore ); - ++num_fragments; - Print_Molecule( system, &m, 1, fragment ); - - /* check if a similar fragment already exists */ - flag = 0; - for( i = 0; i < num_fragment_types; ++i ) - if( !strcmp( fragments[i], fragment ) ) { - ++fragment_count[i]; - flag = 1; - break; - } - - if( flag == 0 ) { - /* it is a new one, add to the fragments list */ - strcpy( fragments[num_fragment_types], fragment ); - fragment_count[num_fragment_types] = 1; - ++num_fragment_types; - } - } - - /* output the results of fragment analysis */ - for( i = 0; i < num_fragment_types; ++i ) - if( strlen(fragments[i]) ) - fprintf( fout, "%d of %s\n", fragment_count[i], fragments[i] ); - fprintf( fout, "\n" ); - fflush( fout ); - - /* compare new bonds to old bonds */ - //for( atom = 0; atom < system->N; ++atom ) { - // fprintf( fout, "atom: %d\n", atom ); fflush( fout ); - // Compare_Bonding( atom, system, control, workspace, - // old_bonds, new_bonds, fout ); - //} - //Copy_Bond_List( system, control, lists ); + int atom, i, flag; + int *mark = workspace->mark; + int num_fragments, num_fragment_types; + char fragment[MAX_ATOM_TYPES]; + char fragments[MAX_FRAGMENT_TYPES][MAX_ATOM_TYPES]; + int fragment_count[MAX_FRAGMENT_TYPES]; + molecule m; + list *new_bonds = (*lists) + BONDS; + //list *old_bonds = (*lists) + OLD_BONDS; + + /* fragment analysis */ + fprintf( fout, "step%d fragments\n", data->step ); + num_fragments = 0; + num_fragment_types = 0; + memset( mark, 0, system->N * sizeof(int) ); + + for ( atom = 0; atom < system->N; ++atom ) + if ( !mark[atom] ) + { + /* discover a new fragment */ + memset( m.mtypes, 0, MAX_ATOM_TYPES * sizeof(int) ); + Visit_Bonds( atom, mark, m.mtypes, system, control, new_bonds, ignore ); + ++num_fragments; + Print_Molecule( system, &m, 1, fragment ); + + /* check if a similar fragment already exists */ + flag = 0; + for ( i = 0; i < num_fragment_types; ++i ) + if ( !strcmp( fragments[i], fragment ) ) + { + ++fragment_count[i]; + flag = 1; + break; + } + + if ( flag == 0 ) + { + /* it is a new one, add to the fragments list */ + strcpy( fragments[num_fragment_types], fragment ); + fragment_count[num_fragment_types] = 1; + ++num_fragment_types; + } + } + + /* output the results of fragment analysis */ + for ( i = 0; i < num_fragment_types; ++i ) + if ( strlen(fragments[i]) ) + fprintf( fout, "%d of %s\n", fragment_count[i], fragments[i] ); + fprintf( fout, "\n" ); + fflush( fout ); + + /* compare new bonds to old bonds */ + //for( atom = 0; atom < system->N; ++atom ) { + // fprintf( fout, "atom: %d\n", atom ); fflush( fout ); + // Compare_Bonding( atom, system, control, workspace, + // old_bonds, new_bonds, fout ); + //} + //Copy_Bond_List( system, control, lists ); } -void Analyze_Silica( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, FILE *fout ) +void Analyze_Silica( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, FILE *fout ) { - int atom, i, j, k, pi, pk, pk_j, newp, coord; - int O_SI_O_count, SI_O_SI_count; - int si_coord[10], ox_coord[10]; - real O_SI_O, SI_O_SI; - list *new_bonds = (*lists) + BONDS; - list *thb_intrs = (*lists) + THREE_BODIES; - - Analyze_Fragments( system, control, data, workspace, lists, fout, 0 ); - - /* analyze atom coordinations */ - for( i = 0; i < 10; ++i ) - si_coord[i] = ox_coord[i] = 0; - - for( atom = 0; atom < system->N; ++atom ) { - coord = 0; - - for( newp = Start_Index( atom, new_bonds ); - newp < End_Index( atom, new_bonds ); ++newp ) - if( new_bonds->select.bond_list[newp].bo_data.BO >= control->bg_cut ) - ++coord; - - if( system->atoms[ atom ].type == SI_ATOM ) { - /*if( coord == 4 ) - full_coord_SI++; - else less_coord_SI++;*/ - ++si_coord[coord]; - } - else if( system->atoms[ atom ].type == O_ATOM ) { - /*if( coord == 2 ) - full_coord_O++; - else less_coord_O++;*/ - ++ox_coord[coord]; + int atom, i, j, k, pi, pk, pk_j, newp, coord; + int O_SI_O_count, SI_O_SI_count; + int si_coord[10], ox_coord[10]; + real O_SI_O, SI_O_SI; + list *new_bonds = (*lists) + BONDS; + list *thb_intrs = (*lists) + THREE_BODIES; + + Analyze_Fragments( system, control, data, workspace, lists, fout, 0 ); + + /* analyze atom coordinations */ + for ( i = 0; i < 10; ++i ) + si_coord[i] = ox_coord[i] = 0; + + for ( atom = 0; atom < system->N; ++atom ) + { + coord = 0; + + for ( newp = Start_Index( atom, new_bonds ); + newp < End_Index( atom, new_bonds ); ++newp ) + if ( new_bonds->select.bond_list[newp].bo_data.BO >= control->bg_cut ) + ++coord; + + if ( system->atoms[ atom ].type == SI_ATOM ) + { + /*if( coord == 4 ) + full_coord_SI++; + else less_coord_SI++;*/ + ++si_coord[coord]; + } + else if ( system->atoms[ atom ].type == O_ATOM ) + { + /*if( coord == 2 ) + full_coord_O++; + else less_coord_O++;*/ + ++ox_coord[coord]; + } } - } - - /* fprintf( fout, "\nFour Coordinated SI: %.2f%\n", - (double)full_coord_SI / (full_coord_SI + less_coord_SI) * 100. ); - fprintf( fout, "Four Coordinated O : %.2f%\n", - (double)full_coord_O / (full_coord_O + less_coord_O ) * 100. ); */ - - fprintf( fout, "Silicon coordinations:\n" ); - for( i = 1; i < 10; ++i ) - if( si_coord[i] ) - fprintf( fout, "\t%d-coord: %d\n", i, si_coord[i] ); - - fprintf( fout, "\nOxygen coordinations:\n" ); - for( i = 1; i < 10; ++i ) - if( ox_coord[i] ) - fprintf( fout, "\t%d-coord: %d\n", i, ox_coord[i] ); - - - /* analyze bond angles */ - O_SI_O = 0; - O_SI_O_count = 0; - - SI_O_SI = 0; - SI_O_SI_count = 0; - - for( j = 0; j < system->N; ++j ) - if( system->atoms[j].type == O_ATOM || system->atoms[j].type == SI_ATOM ) - for( pi = Start_Index(j, new_bonds); pi < End_Index(j, new_bonds); ++pi ) - if( new_bonds->select.bond_list[pi].bo_data.BO >= control->bg_cut ) { - i = new_bonds->select.bond_list[pi].nbr; - - if(system->atoms[i].type==O_ATOM || system->atoms[i].type==SI_ATOM) { - for( pk = Start_Index( pi, thb_intrs ); - pk < End_Index( pi, thb_intrs ); ++pk ) { - k = thb_intrs->select.three_body_list[pk].thb; - pk_j = thb_intrs->select.three_body_list[pk].pthb; - // get k's pointer on j's bond list - - if( new_bonds->select.bond_list[pk_j].bo_data.BO >= - control->bg_cut ) { // physical j&k bond - /*fprintf( fout, "%5d(%d) %5d(%d) %5d(%d) %8.3f\n", - i, system->atoms[i].type, j, system->atoms[j].type, - k, system->atoms[k].type, - thb_intrs->select.three_body_list[pk].theta );*/ - - if( system->atoms[i].type == O_ATOM && - system->atoms[j].type == SI_ATOM && - system->atoms[k].type == O_ATOM ){ - O_SI_O_count++; - O_SI_O += thb_intrs->select.three_body_list[pk].theta; - } - else if ( system->atoms[i].type == SI_ATOM && - system->atoms[j].type == O_ATOM && - system->atoms[k].type == SI_ATOM ){ - SI_O_SI_count++; - SI_O_SI += thb_intrs->select.three_body_list[pk].theta; - } - } - } - } - } - - fprintf( fout, "\nAverage O-Si-O angle: %8.2f\n", - RAD2DEG(O_SI_O / O_SI_O_count) ); - fprintf( fout, "Average Si-O-Si angle: %8.2f\n\n\n", - RAD2DEG(SI_O_SI / SI_O_SI_count) ); - - fflush( fout ); + + /* fprintf( fout, "\nFour Coordinated SI: %.2f%\n", + (double)full_coord_SI / (full_coord_SI + less_coord_SI) * 100. ); + fprintf( fout, "Four Coordinated O : %.2f%\n", + (double)full_coord_O / (full_coord_O + less_coord_O ) * 100. ); */ + + fprintf( fout, "Silicon coordinations:\n" ); + for ( i = 1; i < 10; ++i ) + if ( si_coord[i] ) + fprintf( fout, "\t%d-coord: %d\n", i, si_coord[i] ); + + fprintf( fout, "\nOxygen coordinations:\n" ); + for ( i = 1; i < 10; ++i ) + if ( ox_coord[i] ) + fprintf( fout, "\t%d-coord: %d\n", i, ox_coord[i] ); + + + /* analyze bond angles */ + O_SI_O = 0; + O_SI_O_count = 0; + + SI_O_SI = 0; + SI_O_SI_count = 0; + + for ( j = 0; j < system->N; ++j ) + if ( system->atoms[j].type == O_ATOM || system->atoms[j].type == SI_ATOM ) + for ( pi = Start_Index(j, new_bonds); pi < End_Index(j, new_bonds); ++pi ) + if ( new_bonds->select.bond_list[pi].bo_data.BO >= control->bg_cut ) + { + i = new_bonds->select.bond_list[pi].nbr; + + if (system->atoms[i].type == O_ATOM || system->atoms[i].type == SI_ATOM) + { + for ( pk = Start_Index( pi, thb_intrs ); + pk < End_Index( pi, thb_intrs ); ++pk ) + { + k = thb_intrs->select.three_body_list[pk].thb; + pk_j = thb_intrs->select.three_body_list[pk].pthb; + // get k's pointer on j's bond list + + if ( new_bonds->select.bond_list[pk_j].bo_data.BO >= + control->bg_cut ) // physical j&k bond + { + /*fprintf( fout, "%5d(%d) %5d(%d) %5d(%d) %8.3f\n", + i, system->atoms[i].type, j, system->atoms[j].type, + k, system->atoms[k].type, + thb_intrs->select.three_body_list[pk].theta );*/ + + if ( system->atoms[i].type == O_ATOM && + system->atoms[j].type == SI_ATOM && + system->atoms[k].type == O_ATOM ) + { + O_SI_O_count++; + O_SI_O += thb_intrs->select.three_body_list[pk].theta; + } + else if ( system->atoms[i].type == SI_ATOM && + system->atoms[j].type == O_ATOM && + system->atoms[k].type == SI_ATOM ) + { + SI_O_SI_count++; + SI_O_SI += thb_intrs->select.three_body_list[pk].theta; + } + } + } + } + } + + fprintf( fout, "\nAverage O-Si-O angle: %8.2f\n", + RAD2DEG(O_SI_O / O_SI_O_count) ); + fprintf( fout, "Average Si-O-Si angle: %8.2f\n\n\n", + RAD2DEG(SI_O_SI / SI_O_SI_count) ); + + fflush( fout ); } int Get_Type_of_Molecule( molecule *m ) { - if( m->atom_count == 3 && m->mtypes[1] == 2 && m->mtypes[2] == 1 ) - return WATER; + if ( m->atom_count == 3 && m->mtypes[1] == 2 && m->mtypes[2] == 1 ) + return WATER; - return UNKNOWN; + return UNKNOWN; } -void Calculate_Dipole_Moment( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list *bonds, FILE *fout ) +void Calculate_Dipole_Moment( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list *bonds, FILE *fout ) { - int i, atom, count; - molecule m; - real mu_sum; - rvec tmpvec, mu; - int *mark = workspace->mark; - - //fprintf( fout, "starting dipole moment calculations...\n" ); - - mu_sum = 0; - count = 0; - - for( atom = 0; atom < system->N; ++atom ) - /* start discovering water molecules from the central O atom */ - if( !mark[atom] && system->atoms[atom].type == 2 ) { - rvec_MakeZero( mu ); - - memset( &m, 0, sizeof(molecule) ); - Get_Molecule( atom, &m, mark, system, control, bonds, 0, fout ); - - if( Get_Type_of_Molecule( &m ) == WATER ) { - ++count; - - for( i = 1; i < 2; ++i ) { - Distance_on_T3_Gen( system->atoms[ m.atom_list[0] ].x, - system->atoms[ m.atom_list[i] ].x, - &(system->box), tmpvec ); - rvec_ScaledAdd( mu, -system->atoms[m.atom_list[0]].q / 2.0, tmpvec ); - } - - mu_sum += rvec_Norm( mu ); - } - } - - fprintf( fout, "%7d %10d %10.5f\n", - data->step, count, mu_sum / count * ECxA_to_DEBYE ); - fflush( fout ); + int i, atom, count; + molecule m; + real mu_sum; + rvec tmpvec, mu; + int *mark = workspace->mark; + + //fprintf( fout, "starting dipole moment calculations...\n" ); + + mu_sum = 0; + count = 0; + + for ( atom = 0; atom < system->N; ++atom ) + /* start discovering water molecules from the central O atom */ + if ( !mark[atom] && system->atoms[atom].type == 2 ) + { + rvec_MakeZero( mu ); + + memset( &m, 0, sizeof(molecule) ); + Get_Molecule( atom, &m, mark, system, control, bonds, 0, fout ); + + if ( Get_Type_of_Molecule( &m ) == WATER ) + { + ++count; + + for ( i = 1; i < 2; ++i ) + { + Distance_on_T3_Gen( system->atoms[ m.atom_list[0] ].x, + system->atoms[ m.atom_list[i] ].x, + &(system->box), tmpvec ); + rvec_ScaledAdd( mu, -system->atoms[m.atom_list[0]].q / 2.0, tmpvec ); + } + + mu_sum += rvec_Norm( mu ); + } + } + + fprintf( fout, "%7d %10d %10.5f\n", + data->step, count, mu_sum / count * ECxA_to_DEBYE ); + fflush( fout ); } void Copy_Positions( reax_system *system, static_storage *workspace ) { - int i; - - for( i = 0; i < system->N; ++i ) - rvec_Copy( workspace->x_old[i], system->atoms[i].x ); + int i; + + for ( i = 0; i < system->N; ++i ) + rvec_Copy( workspace->x_old[i], system->atoms[i].x ); } -void Calculate_Drift( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - FILE *fout ) +void Calculate_Drift( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + FILE *fout ) { - int i, type; - int count[MAX_ATOM_TYPES]; - real drift; - rvec driftvec; - real sum_sqr_drift[MAX_ATOM_TYPES], sum_drift[MAX_ATOM_TYPES]; + int i, type; + int count[MAX_ATOM_TYPES]; + real drift; + rvec driftvec; + real sum_sqr_drift[MAX_ATOM_TYPES], sum_drift[MAX_ATOM_TYPES]; - for( i = 0; i < MAX_ATOM_TYPES; ++i ) + for ( i = 0; i < MAX_ATOM_TYPES; ++i ) { - count[i] = 0; - sum_sqr_drift[i] = sum_drift[i] = 0.0; + count[i] = 0; + sum_sqr_drift[i] = sum_drift[i] = 0.0; } - for( i = 0; i < system->N; ++i ) - //if( control->restrict_type == -1 || - // system->atoms[i].type == control->restrict_type ) - if( workspace->x_old[i][0] > -system->box.box_norms[0] && - workspace->x_old[i][1] > -system->box.box_norms[1] && - workspace->x_old[i][2] > -system->box.box_norms[2] ) - { - type = system->atoms[i].type; - ++count[type]; - - Distance_on_T3_Gen( workspace->x_old[i], system->atoms[i].x, - &(system->box), driftvec ); - - if( fabs( driftvec[0] ) >= system->box.box_norms[0] / 2.0 - 2.0 || - fabs( driftvec[0] ) >= system->box.box_norms[0] / 2.0 - 2.0 || - fabs( driftvec[0] ) >= system->box.box_norms[0] / 2.0 - 2.0 ) { - /* the atom has moved almost half the box size. - exclude it from further drift computations as it might have an - improper contribution due to periodic boudnaries. */ - workspace->x_old[i][0] = -999999999999.0; - workspace->x_old[i][2] = -999999999999.0; - workspace->x_old[i][2] = -999999999999.0; - continue; - } - - drift = rvec_Norm_Sqr( driftvec ); - sum_sqr_drift[type] += drift; - sum_drift[type] += SQRT( drift ); - } - - fprintf( fout, "%7d oxy %6d %10.6f\n", - data->step, count[2], sum_sqr_drift[2] / count[2] ); - fprintf( fout, "%7d hyd %6d %10.6f\n", - data->step, count[1], sum_sqr_drift[1] / count[1] ); - - fflush( fout ); + for ( i = 0; i < system->N; ++i ) + //if( control->restrict_type == -1 || + // system->atoms[i].type == control->restrict_type ) + if ( workspace->x_old[i][0] > -system->box.box_norms[0] && + workspace->x_old[i][1] > -system->box.box_norms[1] && + workspace->x_old[i][2] > -system->box.box_norms[2] ) + { + type = system->atoms[i].type; + ++count[type]; + + Distance_on_T3_Gen( workspace->x_old[i], system->atoms[i].x, + &(system->box), driftvec ); + + if ( fabs( driftvec[0] ) >= system->box.box_norms[0] / 2.0 - 2.0 || + fabs( driftvec[0] ) >= system->box.box_norms[0] / 2.0 - 2.0 || + fabs( driftvec[0] ) >= system->box.box_norms[0] / 2.0 - 2.0 ) + { + /* the atom has moved almost half the box size. + exclude it from further drift computations as it might have an + improper contribution due to periodic boudnaries. */ + workspace->x_old[i][0] = -999999999999.0; + workspace->x_old[i][2] = -999999999999.0; + workspace->x_old[i][2] = -999999999999.0; + continue; + } + + drift = rvec_Norm_Sqr( driftvec ); + sum_sqr_drift[type] += drift; + sum_drift[type] += SQRT( drift ); + } + + fprintf( fout, "%7d oxy %6d %10.6f\n", + data->step, count[2], sum_sqr_drift[2] / count[2] ); + fprintf( fout, "%7d hyd %6d %10.6f\n", + data->step, count[1], sum_sqr_drift[1] / count[1] ); + + fflush( fout ); } -void Calculate_Density_3DMesh( reax_system *system, simulation_data *data, - FILE *fout ) +void Calculate_Density_3DMesh( reax_system *system, simulation_data *data, + FILE *fout ) { - int i, j, k; - int occupied_cells; - int ***cell_counter; - ivec my_cell; - rvec mesh_cell_lens = { 1, 1, 1 }; - ivec mesh_dims; - real occupied_vol, density; - - /* determine the mesh dimensions based on the current box size */ - for( i = 0; i < 3; ++i ) - mesh_dims[i] = system->box.box_norms[i] / mesh_cell_lens[i] + 0.99; - - fprintf( stderr, "mesh_dims: %3d %3d %3d\n", - mesh_dims[0], mesh_dims[1], mesh_dims[2] ); - - /* allocate counter for each mesh cell */ - cell_counter = (int ***) calloc( mesh_dims[0], sizeof(int) ); - - for( i = 0; i < mesh_dims[0]; ++i ) { - cell_counter[i] = (int **) calloc( mesh_dims[1], sizeof(int) ); - - for( j = 0; j < mesh_dims[1]; ++j ) - cell_counter[i][j] = (int *) calloc( mesh_dims[2], sizeof(int) ); - } - - - /* go over the atoms and assign each into their corresponding mesh cell */ - for( i = 0; i < system->N; ++i ) { - my_cell[0] = system->atoms[i].x[0] / mesh_cell_lens[0]; - my_cell[1] = system->atoms[i].x[1] / mesh_cell_lens[1]; - my_cell[2] = system->atoms[i].x[2] / mesh_cell_lens[2]; - - cell_counter[ my_cell[0] ][ my_cell[1] ][ my_cell[2] ]++; - } - - - /* calculate volume occupied */ - occupied_cells = 0; - for( i = 0; i < mesh_dims[0]; ++i ) - for( j = 0; j < mesh_dims[1]; ++j ) - for( k = 0; k < mesh_dims[2]; ++k ) - if( cell_counter[i][j][k] ) - ++occupied_cells; - - occupied_vol = - occupied_cells * mesh_cell_lens[0] * mesh_cell_lens[1] * mesh_cell_lens[2]; - - fprintf( stderr, "occupied cells: %8d\n", occupied_cells ); - fprintf( stderr, "occupied vol : %8.2f\n", occupied_vol ); - fprintf( stderr, "system volume : %8.2f\n", system->box.volume ); - fprintf( stderr, "system mass : %8.2f\n", data->M ); - - density = data->M * AMU_to_GRAM / (occupied_vol * POW( ANG_to_CM, 3 )); - fprintf( stderr, "density : %g\n", density ); - fprintf( stderr, "AMU_to_GRAM : %g\n", AMU_to_GRAM ); - fprintf( stderr, "ANG_to_CM : %g\n", ANG_to_CM ); + int i, j, k; + int occupied_cells; + int ***cell_counter; + ivec my_cell; + rvec mesh_cell_lens = { 1, 1, 1 }; + ivec mesh_dims; + real occupied_vol, density; + + /* determine the mesh dimensions based on the current box size */ + for ( i = 0; i < 3; ++i ) + mesh_dims[i] = system->box.box_norms[i] / mesh_cell_lens[i] + 0.99; + + fprintf( stderr, "mesh_dims: %3d %3d %3d\n", + mesh_dims[0], mesh_dims[1], mesh_dims[2] ); + + /* allocate counter for each mesh cell */ + cell_counter = (int ***) calloc( mesh_dims[0], sizeof(int) ); + + for ( i = 0; i < mesh_dims[0]; ++i ) + { + cell_counter[i] = (int **) calloc( mesh_dims[1], sizeof(int) ); + + for ( j = 0; j < mesh_dims[1]; ++j ) + cell_counter[i][j] = (int *) calloc( mesh_dims[2], sizeof(int) ); + } + + + /* go over the atoms and assign each into their corresponding mesh cell */ + for ( i = 0; i < system->N; ++i ) + { + my_cell[0] = system->atoms[i].x[0] / mesh_cell_lens[0]; + my_cell[1] = system->atoms[i].x[1] / mesh_cell_lens[1]; + my_cell[2] = system->atoms[i].x[2] / mesh_cell_lens[2]; + + cell_counter[ my_cell[0] ][ my_cell[1] ][ my_cell[2] ]++; + } + + + /* calculate volume occupied */ + occupied_cells = 0; + for ( i = 0; i < mesh_dims[0]; ++i ) + for ( j = 0; j < mesh_dims[1]; ++j ) + for ( k = 0; k < mesh_dims[2]; ++k ) + if ( cell_counter[i][j][k] ) + ++occupied_cells; + + occupied_vol = + occupied_cells * mesh_cell_lens[0] * mesh_cell_lens[1] * mesh_cell_lens[2]; + + fprintf( stderr, "occupied cells: %8d\n", occupied_cells ); + fprintf( stderr, "occupied vol : %8.2f\n", occupied_vol ); + fprintf( stderr, "system volume : %8.2f\n", system->box.volume ); + fprintf( stderr, "system mass : %8.2f\n", data->M ); + + density = data->M * AMU_to_GRAM / (occupied_vol * POW( ANG_to_CM, 3 )); + fprintf( stderr, "density : %g\n", density ); + fprintf( stderr, "AMU_to_GRAM : %g\n", AMU_to_GRAM ); + fprintf( stderr, "ANG_to_CM : %g\n", ANG_to_CM ); } -void Calculate_Density_Slice( reax_system *system, simulation_data *data, - FILE *fout ) +void Calculate_Density_Slice( reax_system *system, simulation_data *data, + FILE *fout ) { - real slice_thickness = 0.5; - int *slice_occ; - int i, num_slices, my_slice, max_occ = 0; - - /* allocate counter */ - num_slices = system->box.box_norms[2] / slice_thickness + 1.; - slice_occ = (int*) calloc( num_slices, sizeof(int) ); - - /* distribute atoms to slices */ - for( i = 0; i < system->N; ++i ) { - my_slice = system->atoms[i].x[2] / slice_thickness; - slice_occ[ my_slice ]++; - } - - /* determine maximum occupancy */ - for( i = 0; i < num_slices; ++i ) { - fprintf( stderr, "occ[%d]: %d\n", i, slice_occ[i] ); - if( slice_occ[i] > max_occ ) - max_occ = slice_occ[i]; - } - - /* find luzzatti-interface slice */ - for( i = 0; i < num_slices; ++i ) - if( (real)slice_occ[i] / max_occ > 0.5 ) { - fprintf( stderr, "%d - %d is the luzzatti interface\n", i-1, i ); - break; + real slice_thickness = 0.5; + int *slice_occ; + int i, num_slices, my_slice, max_occ = 0; + + /* allocate counter */ + num_slices = system->box.box_norms[2] / slice_thickness + 1.; + slice_occ = (int*) calloc( num_slices, sizeof(int) ); + + /* distribute atoms to slices */ + for ( i = 0; i < system->N; ++i ) + { + my_slice = system->atoms[i].x[2] / slice_thickness; + slice_occ[ my_slice ]++; + } + + /* determine maximum occupancy */ + for ( i = 0; i < num_slices; ++i ) + { + fprintf( stderr, "occ[%d]: %d\n", i, slice_occ[i] ); + if ( slice_occ[i] > max_occ ) + max_occ = slice_occ[i]; } + + /* find luzzatti-interface slice */ + for ( i = 0; i < num_slices; ++i ) + if ( (real)slice_occ[i] / max_occ > 0.5 ) + { + fprintf( stderr, "%d - %d is the luzzatti interface\n", i - 1, i ); + break; + } } -void Analysis( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Analysis( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int steps; - - steps = data->step - data->prev_steps; - // fprintf( stderr, "prev_steps: %d\n", data->prev_steps ); - - if( steps == 1 ) { - if( control->molec_anal == REACTIONS ) - Copy_Bond_List( system, control, lists ); - if( control->diffusion_coef ) - Copy_Positions( system, workspace ); - } - - /****** Molecular Analysis ******/ - if( control->molec_anal && steps%control->freq_molec_anal == 0 ) { - if( control->molec_anal == FRAGMENTS ) { - /* discover molecules */ - Analyze_Fragments( system, control, data, workspace, lists, - out_control->mol, 0 ); - /* discover fragments without the ignored atoms */ - if( control->num_ignored ) - Analyze_Fragments( system, control, data, workspace, lists, - out_control->ign, 1 ); + int steps; + + steps = data->step - data->prev_steps; + // fprintf( stderr, "prev_steps: %d\n", data->prev_steps ); + + if ( steps == 1 ) + { + if ( control->molec_anal == REACTIONS ) + Copy_Bond_List( system, control, lists ); + if ( control->diffusion_coef ) + Copy_Positions( system, workspace ); } - else if( control->molec_anal == REACTIONS ) - /* discover molecular changes - reactions */ - Analyze_Molecules( system, control, data, workspace, - lists, out_control->mol ); - } - - /****** Electric Dipole Moment ******/ - if( control->dipole_anal && steps%control->freq_dipole_anal == 0 ) - Calculate_Dipole_Moment( system, control, data, workspace, - (*lists) + BONDS, out_control->dpl ); - - /****** Drift ******/ - if( control->diffusion_coef && steps%control->freq_diffusion_coef == 0 ) - Calculate_Drift( system, control, data, workspace, out_control->drft ); + + /****** Molecular Analysis ******/ + if ( control->molec_anal && steps % control->freq_molec_anal == 0 ) + { + if ( control->molec_anal == FRAGMENTS ) + { + /* discover molecules */ + Analyze_Fragments( system, control, data, workspace, lists, + out_control->mol, 0 ); + /* discover fragments without the ignored atoms */ + if ( control->num_ignored ) + Analyze_Fragments( system, control, data, workspace, lists, + out_control->ign, 1 ); + } + else if ( control->molec_anal == REACTIONS ) + /* discover molecular changes - reactions */ + Analyze_Molecules( system, control, data, workspace, + lists, out_control->mol ); + } + + /****** Electric Dipole Moment ******/ + if ( control->dipole_anal && steps % control->freq_dipole_anal == 0 ) + Calculate_Dipole_Moment( system, control, data, workspace, + (*lists) + BONDS, out_control->dpl ); + + /****** Drift ******/ + if ( control->diffusion_coef && steps % control->freq_diffusion_coef == 0 ) + Calculate_Drift( system, control, data, workspace, out_control->drft ); #if defined(DEBUG) - fprintf( stderr, "analysis... done\n" ); + fprintf( stderr, "analysis... done\n" ); #endif } diff --git a/puremd_rc_1003/sPuReMD/analyze.h b/puremd_rc_1003/sPuReMD/analyze.h index 01c193ad..e296e57a 100644 --- a/puremd_rc_1003/sPuReMD/analyze.h +++ b/puremd_rc_1003/sPuReMD/analyze.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -24,18 +24,18 @@ #include "mytypes.h" -void Analysis( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); +void Analysis( reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls* ); //void Copy_Bond_List( reax_system*, control_params*, list** ); -//void Analyze_Molecules( reax_system*, control_params*, simulation_data*, +//void Analyze_Molecules( reax_system*, control_params*, simulation_data*, // static_storage*, list**, FILE* ); -//void Analyze_Bonding( reax_system*, control_params*, simulation_data*, +//void Analyze_Bonding( reax_system*, control_params*, simulation_data*, // static_storage*, list**, FILE* ); -//void Analyze_Silica( reax_system*, control_params*, simulation_data*, +//void Analyze_Silica( reax_system*, control_params*, simulation_data*, // static_storage*, list**, FILE* ); //void Calculate_Dipole_Moment( reax_system*, control_params*, simulation_data*, @@ -43,7 +43,7 @@ void Analysis( reax_system*, control_params*, simulation_data*, //void Copy_Positions( reax_system*, static_storage* ); -//void Calculate_Drift( reax_system*, control_params*, +//void Calculate_Drift( reax_system*, control_params*, // simulation_data*, static_storage*, FILE* ); //void Calculate_Density_3DMesh( reax_system*, simulation_data*, FILE* ); diff --git a/puremd_rc_1003/sPuReMD/bond_orders.c b/puremd_rc_1003/sPuReMD/bond_orders.c index 718659da..34818468 100644 --- a/puremd_rc_1003/sPuReMD/bond_orders.c +++ b/puremd_rc_1003/sPuReMD/bond_orders.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -28,606 +28,619 @@ inline real Cf45( real p1, real p2 ) { - return -EXP(-p2 / 2) / - ( SQR( EXP(-p1 / 2) + EXP(p1 / 2) ) * (EXP(-p2 / 2) + EXP(p2 / 2)) ); + return -EXP(-p2 / 2) / + ( SQR( EXP(-p1 / 2) + EXP(p1 / 2) ) * (EXP(-p2 / 2) + EXP(p2 / 2)) ); } #ifdef TEST_FORCES -void Get_dBO( reax_system *system, list **lists, - int i, int pj, real C, rvec *v ) +void Get_dBO( reax_system *system, list **lists, + int i, int pj, real C, rvec *v ) { - list *bonds = (*lists) + BONDS; - list *dBOs = (*lists) + DBO; - int start_pj, end_pj, k; - - pj = bonds->select.bond_list[pj].dbond_index; - start_pj = Start_Index(pj, dBOs); - end_pj = End_Index(pj, dBOs); - - for( k = start_pj; k < end_pj; ++k ) - rvec_Scale( v[dBOs->select.dbo_list[k].wrt], - C, dBOs->select.dbo_list[k].dBO ); + list *bonds = (*lists) + BONDS; + list *dBOs = (*lists) + DBO; + int start_pj, end_pj, k; + + pj = bonds->select.bond_list[pj].dbond_index; + start_pj = Start_Index(pj, dBOs); + end_pj = End_Index(pj, dBOs); + + for ( k = start_pj; k < end_pj; ++k ) + rvec_Scale( v[dBOs->select.dbo_list[k].wrt], + C, dBOs->select.dbo_list[k].dBO ); } -void Get_dBOpinpi2( reax_system *system, list **lists, - int i, int pj, real Cpi, real Cpi2, rvec *vpi, rvec *vpi2 ) +void Get_dBOpinpi2( reax_system *system, list **lists, + int i, int pj, real Cpi, real Cpi2, rvec *vpi, rvec *vpi2 ) { - list *bonds = (*lists) + BONDS; - list *dBOs = (*lists) + DBO; - dbond_data *dbo_k; - int start_pj, end_pj, k; - - pj = bonds->select.bond_list[pj].dbond_index; - start_pj = Start_Index(pj, dBOs); - end_pj = End_Index(pj, dBOs); - - for( k = start_pj; k < end_pj; ++k ) { - dbo_k = &(dBOs->select.dbo_list[k]); - rvec_Scale( vpi[dbo_k->wrt], Cpi, dbo_k->dBOpi ); - rvec_Scale( vpi2[dbo_k->wrt], Cpi2, dbo_k->dBOpi2 ); - } + list *bonds = (*lists) + BONDS; + list *dBOs = (*lists) + DBO; + dbond_data *dbo_k; + int start_pj, end_pj, k; + + pj = bonds->select.bond_list[pj].dbond_index; + start_pj = Start_Index(pj, dBOs); + end_pj = End_Index(pj, dBOs); + + for ( k = start_pj; k < end_pj; ++k ) + { + dbo_k = &(dBOs->select.dbo_list[k]); + rvec_Scale( vpi[dbo_k->wrt], Cpi, dbo_k->dBOpi ); + rvec_Scale( vpi2[dbo_k->wrt], Cpi2, dbo_k->dBOpi2 ); + } } -void Add_dBO( reax_system *system, list **lists, - int i, int pj, real C, rvec *v ) +void Add_dBO( reax_system *system, list **lists, + int i, int pj, real C, rvec *v ) { - list *bonds = (*lists) + BONDS; - list *dBOs = (*lists) + DBO; - int start_pj, end_pj, k; + list *bonds = (*lists) + BONDS; + list *dBOs = (*lists) + DBO; + int start_pj, end_pj, k; - pj = bonds->select.bond_list[pj].dbond_index; - start_pj = Start_Index(pj, dBOs); - end_pj = End_Index(pj, dBOs); - - //fprintf( stderr, "i=%d j=%d start=%d end=%d\n", i, pj, start_pj, end_pj ); + pj = bonds->select.bond_list[pj].dbond_index; + start_pj = Start_Index(pj, dBOs); + end_pj = End_Index(pj, dBOs); - for( k = start_pj; k < end_pj; ++k ) - rvec_ScaledAdd( v[dBOs->select.dbo_list[k].wrt], - C, dBOs->select.dbo_list[k].dBO ); + //fprintf( stderr, "i=%d j=%d start=%d end=%d\n", i, pj, start_pj, end_pj ); + + for ( k = start_pj; k < end_pj; ++k ) + rvec_ScaledAdd( v[dBOs->select.dbo_list[k].wrt], + C, dBOs->select.dbo_list[k].dBO ); } -void Add_dBOpinpi2( reax_system *system, list **lists, - int i, int pj, real Cpi, real Cpi2, rvec *vpi, rvec *vpi2 ) +void Add_dBOpinpi2( reax_system *system, list **lists, + int i, int pj, real Cpi, real Cpi2, rvec *vpi, rvec *vpi2 ) { - list *bonds = (*lists) + BONDS; - list *dBOs = (*lists) + DBO; - dbond_data *dbo_k; - int start_pj, end_pj, k; + list *bonds = (*lists) + BONDS; + list *dBOs = (*lists) + DBO; + dbond_data *dbo_k; + int start_pj, end_pj, k; - pj = bonds->select.bond_list[pj].dbond_index; - start_pj = Start_Index(pj, dBOs); - end_pj = End_Index(pj, dBOs); + pj = bonds->select.bond_list[pj].dbond_index; + start_pj = Start_Index(pj, dBOs); + end_pj = End_Index(pj, dBOs); - for( k = start_pj; k < end_pj; ++k ) + for ( k = start_pj; k < end_pj; ++k ) { - dbo_k = &(dBOs->select.dbo_list[k]); - rvec_ScaledAdd( vpi[dbo_k->wrt], Cpi, dbo_k->dBOpi ); - rvec_ScaledAdd( vpi2[dbo_k->wrt], Cpi2, dbo_k->dBOpi2 ); + dbo_k = &(dBOs->select.dbo_list[k]); + rvec_ScaledAdd( vpi[dbo_k->wrt], Cpi, dbo_k->dBOpi ); + rvec_ScaledAdd( vpi2[dbo_k->wrt], Cpi2, dbo_k->dBOpi2 ); } } -void Add_dBO_to_Forces( reax_system *system, list **lists, - int i, int pj, real C ) +void Add_dBO_to_Forces( reax_system *system, list **lists, + int i, int pj, real C ) { - list *bonds = (*lists) + BONDS; - list *dBOs = (*lists) + DBO; - int start_pj, end_pj, k; + list *bonds = (*lists) + BONDS; + list *dBOs = (*lists) + DBO; + int start_pj, end_pj, k; - pj = bonds->select.bond_list[pj].dbond_index; - start_pj = Start_Index(pj, dBOs); - end_pj = End_Index(pj, dBOs); + pj = bonds->select.bond_list[pj].dbond_index; + start_pj = Start_Index(pj, dBOs); + end_pj = End_Index(pj, dBOs); - for( k = start_pj; k < end_pj; ++k ) - rvec_ScaledAdd( system->atoms[dBOs->select.dbo_list[k].wrt].f, - C, dBOs->select.dbo_list[k].dBO ); + for ( k = start_pj; k < end_pj; ++k ) + rvec_ScaledAdd( system->atoms[dBOs->select.dbo_list[k].wrt].f, + C, dBOs->select.dbo_list[k].dBO ); } -void Add_dBOpinpi2_to_Forces( reax_system *system, list **lists, - int i, int pj, real Cpi, real Cpi2 ) +void Add_dBOpinpi2_to_Forces( reax_system *system, list **lists, + int i, int pj, real Cpi, real Cpi2 ) { - list *bonds = (*lists) + BONDS; - list *dBOs = (*lists) + DBO; - dbond_data *dbo_k; - int start_pj, end_pj, k; + list *bonds = (*lists) + BONDS; + list *dBOs = (*lists) + DBO; + dbond_data *dbo_k; + int start_pj, end_pj, k; - pj = bonds->select.bond_list[pj].dbond_index; - start_pj = Start_Index(pj, dBOs); - end_pj = End_Index(pj, dBOs); + pj = bonds->select.bond_list[pj].dbond_index; + start_pj = Start_Index(pj, dBOs); + end_pj = End_Index(pj, dBOs); - for( k = start_pj; k < end_pj; ++k ) + for ( k = start_pj; k < end_pj; ++k ) { - dbo_k = &(dBOs->select.dbo_list[k]); - rvec_ScaledAdd( system->atoms[dbo_k->wrt].f, Cpi, dbo_k->dBOpi ); - rvec_ScaledAdd( system->atoms[dbo_k->wrt].f, Cpi2, dbo_k->dBOpi2 ); + dbo_k = &(dBOs->select.dbo_list[k]); + rvec_ScaledAdd( system->atoms[dbo_k->wrt].f, Cpi, dbo_k->dBOpi ); + rvec_ScaledAdd( system->atoms[dbo_k->wrt].f, Cpi2, dbo_k->dBOpi2 ); } } void Add_dDelta( reax_system *system, list **lists, int i, real C, rvec *v ) { - list *dDeltas = &((*lists)[DDELTA]); - int start = Start_Index(i, dDeltas); - int end = End_Index(i, dDeltas); - int k; - - for( k = start; k < end; ++k ) - rvec_ScaledAdd( v[dDeltas->select.dDelta_list[k].wrt], - C, dDeltas->select.dDelta_list[k].dVal ); + list *dDeltas = &((*lists)[DDELTA]); + int start = Start_Index(i, dDeltas); + int end = End_Index(i, dDeltas); + int k; + + for ( k = start; k < end; ++k ) + rvec_ScaledAdd( v[dDeltas->select.dDelta_list[k].wrt], + C, dDeltas->select.dDelta_list[k].dVal ); } void Add_dDelta_to_Forces( reax_system *system, list **lists, int i, real C ) { - list *dDeltas = &((*lists)[DDELTA]); - int start = Start_Index(i, dDeltas); - int end = End_Index(i, dDeltas); - int k; - - for( k = start; k < end; ++k ) - rvec_ScaledAdd( system->atoms[dDeltas->select.dDelta_list[k].wrt].f, - C, dDeltas->select.dDelta_list[k].dVal ); + list *dDeltas = &((*lists)[DDELTA]); + int start = Start_Index(i, dDeltas); + int end = End_Index(i, dDeltas); + int k; + + for ( k = start; k < end; ++k ) + rvec_ScaledAdd( system->atoms[dDeltas->select.dDelta_list[k].wrt].f, + C, dDeltas->select.dDelta_list[k].dVal ); } -void Calculate_dBO( int i, int pj, static_storage *workspace, list **lists, - int *top ) +void Calculate_dBO( int i, int pj, static_storage *workspace, list **lists, + int *top ) { - /* Initializations */ - int j, k, l, start_i, end_i, end_j; - rvec dDeltap_self, dBOp; - list *bonds, *dBOs; - bond_data *nbr_l, *nbr_k; - bond_order_data *bo_ij; - dbond_data *top_dbo; - - bonds = (*lists)+BONDS; - dBOs = (*lists)+DBO; - - j = bonds->select.bond_list[pj].nbr; - bo_ij = &(bonds->select.bond_list[pj].bo_data); - - /*rvec due_j[1000], due_i[1000]; - rvec due_j_pi[1000], due_i_pi[1000]; - - memset(due_j, 0, sizeof(rvec)*1000 ); - memset(due_i, 0, sizeof(rvec)*1000 ); - memset(due_j_pi, 0, sizeof(rvec)*1000 ); - memset(due_i_pi, 0, sizeof(rvec)*1000 );*/ - - //fprintf( stderr,"dbo %d-%d\n",workspace->orig_id[i],workspace->orig_id[j] ); - - start_i = Start_Index(i, bonds); - end_i = End_Index(i, bonds); - - l = Start_Index(j, bonds); - end_j = End_Index(j, bonds); - - top_dbo = &(dBOs->select.dbo_list[ (*top) ]); - - for( k = start_i; k < end_i; ++k ) { - nbr_k = &(bonds->select.bond_list[k]); - //fprintf( stderr, "\tnbr_k = %d\n", workspace->orig_id[nbr_k->nbr] ); - - for( ; l < end_j && bonds->select.bond_list[l].nbr < nbr_k->nbr; ++l ) { - /* These are the neighbors of j which aren't in the neighbor_list of i - Note that they might also include i! */ - nbr_l = &(bonds->select.bond_list[l]); - top_dbo->wrt = nbr_l->nbr; - rvec_Copy( dBOp, nbr_l->bo_data.dBOp ); - //fprintf( stderr,"\t\tnbr_l = %d\n",workspace->orig_id[nbr_l->nbr] ); - - rvec_Scale( top_dbo->dBO, -bo_ij->C3dbo, dBOp ); // dBO, 3rd - rvec_Scale( top_dbo->dBOpi, -bo_ij->C4dbopi, dBOp ); // dBOpi, 4th - rvec_Scale( top_dbo->dBOpi2, -bo_ij->C4dbopi2, dBOp );// dBOpipi, 4th - //rvec_ScaledAdd(due_j[top_dbo->wrt],-bo_ij->BO*bo_ij->A2_ji, dBOp); - - if( nbr_l->nbr == i ) { - rvec_Copy( dDeltap_self, workspace->dDeltap_self[i] ); - - /* dBO */ - rvec_ScaledAdd( top_dbo->dBO, bo_ij->C1dbo, bo_ij->dBOp ); //1st - rvec_ScaledAdd( top_dbo->dBO, bo_ij->C2dbo, dDeltap_self ); //2nd - - /* dBOpi */ - rvec_ScaledAdd(top_dbo->dBOpi,bo_ij->C1dbopi,bo_ij->dln_BOp_pi);//1 - rvec_ScaledAdd(top_dbo->dBOpi,bo_ij->C2dbopi,bo_ij->dBOp); //2nd - rvec_ScaledAdd(top_dbo->dBOpi,bo_ij->C3dbopi,dDeltap_self); //3rd - - /* dBOpp, 1st */ - rvec_ScaledAdd(top_dbo->dBOpi2,bo_ij->C1dbopi2,bo_ij->dln_BOp_pi2); - rvec_ScaledAdd(top_dbo->dBOpi2,bo_ij->C2dbopi2,bo_ij->dBOp); //2nd - rvec_ScaledAdd(top_dbo->dBOpi2,bo_ij->C3dbopi2,dDeltap_self);//3rd - - /* do the adjustments on i */ - //rvec_ScaledAdd( due_i[i], - //bo_ij->A0_ij + bo_ij->BO * bo_ij->A1_ij, bo_ij->dBOp );//1st,dBO - //rvec_ScaledAdd( due_i[i], bo_ij->BO * bo_ij->A2_ij, - //dDeltap_self ); //2nd, dBO - } - - //rvec_Add( workspace->dDelta[nbr_l->nbr], top_dbo->dBO ); - ++(*top), ++top_dbo; - } - - /* Now we are processing neighbor k of i. */ - top_dbo->wrt = nbr_k->nbr; - rvec_Copy( dBOp, nbr_k->bo_data.dBOp ); - - rvec_Scale( top_dbo->dBO, -bo_ij->C2dbo, dBOp ); //dBO-2 - rvec_Scale( top_dbo->dBOpi, -bo_ij->C3dbopi, dBOp ); //dBOpi-3 - rvec_Scale( top_dbo->dBOpi2, -bo_ij->C3dbopi2, dBOp );//dBOpp-3 - //rvec_ScaledAdd(due_i[top_dbo->wrt],-bo_ij->BO*bo_ij->A2_ij,dBOp);//dBO-2 - - // fprintf( stderr, "\tnbr_k = %d, nbr_l = %d, l = %d, end_j = %d\n", - // workspace->orig_id[nbr_k->nbr], - // workspace->orig_id[bonds->select.bond_list[l].nbr], l, end_j ); - - if( l < end_j && bonds->select.bond_list[l].nbr == nbr_k->nbr ) { - /* This is a common neighbor of i and j. */ - nbr_l = &(bonds->select.bond_list[l]); - rvec_Copy( dBOp, nbr_l->bo_data.dBOp ); - - rvec_ScaledAdd( top_dbo->dBO, -bo_ij->C3dbo, dBOp ); //dBO,3rd - rvec_ScaledAdd( top_dbo->dBOpi, -bo_ij->C4dbopi, dBOp ); //dBOpi,4th - rvec_ScaledAdd( top_dbo->dBOpi2, -bo_ij->C4dbopi2, dBOp );//dBOpp.4th - ++l; - - //rvec_ScaledAdd( due_j[top_dbo->wrt], -bo_ij->BO * bo_ij->A2_ji, - //nbr_l->bo_data.dBOp ); //3rd, dBO - } - else if( k == pj ) { - /* This negihbor is j. */ - rvec_Copy( dDeltap_self, workspace->dDeltap_self[j] ); - - rvec_ScaledAdd( top_dbo->dBO, -bo_ij->C1dbo, bo_ij->dBOp );// 1st, dBO - rvec_ScaledAdd( top_dbo->dBO, bo_ij->C3dbo, dDeltap_self );// 3rd, dBO - - /* dBOpi, 1st */ - rvec_ScaledAdd(top_dbo->dBOpi,-bo_ij->C1dbopi,bo_ij->dln_BOp_pi); - rvec_ScaledAdd(top_dbo->dBOpi,-bo_ij->C2dbopi,bo_ij->dBOp); //2nd - rvec_ScaledAdd( top_dbo->dBOpi, bo_ij->C4dbopi, dDeltap_self ); //4th - - /* dBOpi2, 1st */ - rvec_ScaledAdd(top_dbo->dBOpi2,-bo_ij->C1dbopi2,bo_ij->dln_BOp_pi2 ); - rvec_ScaledAdd(top_dbo->dBOpi2,-bo_ij->C2dbopi2,bo_ij->dBOp ); //2nd - rvec_ScaledAdd(top_dbo->dBOpi2,bo_ij->C4dbopi2,dDeltap_self ); //4th - - //rvec_ScaledAdd( due_j[j], -(bo_ij->A0_ij + bo_ij->BO*bo_ij->A1_ij), - //bo_ij->dBOp ); //1st, dBO - //rvec_ScaledAdd( due_j[j], bo_ij->BO * bo_ij->A2_ji, - //workspace->dDeltap_self[j] ); //3rd, dBO + /* Initializations */ + int j, k, l, start_i, end_i, end_j; + rvec dDeltap_self, dBOp; + list *bonds, *dBOs; + bond_data *nbr_l, *nbr_k; + bond_order_data *bo_ij; + dbond_data *top_dbo; + + bonds = (*lists) + BONDS; + dBOs = (*lists) + DBO; + + j = bonds->select.bond_list[pj].nbr; + bo_ij = &(bonds->select.bond_list[pj].bo_data); + + /*rvec due_j[1000], due_i[1000]; + rvec due_j_pi[1000], due_i_pi[1000]; + + memset(due_j, 0, sizeof(rvec)*1000 ); + memset(due_i, 0, sizeof(rvec)*1000 ); + memset(due_j_pi, 0, sizeof(rvec)*1000 ); + memset(due_i_pi, 0, sizeof(rvec)*1000 );*/ + + //fprintf( stderr,"dbo %d-%d\n",workspace->orig_id[i],workspace->orig_id[j] ); + + start_i = Start_Index(i, bonds); + end_i = End_Index(i, bonds); + + l = Start_Index(j, bonds); + end_j = End_Index(j, bonds); + + top_dbo = &(dBOs->select.dbo_list[ (*top) ]); + + for ( k = start_i; k < end_i; ++k ) + { + nbr_k = &(bonds->select.bond_list[k]); + //fprintf( stderr, "\tnbr_k = %d\n", workspace->orig_id[nbr_k->nbr] ); + + for ( ; l < end_j && bonds->select.bond_list[l].nbr < nbr_k->nbr; ++l ) + { + /* These are the neighbors of j which aren't in the neighbor_list of i + Note that they might also include i! */ + nbr_l = &(bonds->select.bond_list[l]); + top_dbo->wrt = nbr_l->nbr; + rvec_Copy( dBOp, nbr_l->bo_data.dBOp ); + //fprintf( stderr,"\t\tnbr_l = %d\n",workspace->orig_id[nbr_l->nbr] ); + + rvec_Scale( top_dbo->dBO, -bo_ij->C3dbo, dBOp ); // dBO, 3rd + rvec_Scale( top_dbo->dBOpi, -bo_ij->C4dbopi, dBOp ); // dBOpi, 4th + rvec_Scale( top_dbo->dBOpi2, -bo_ij->C4dbopi2, dBOp );// dBOpipi, 4th + //rvec_ScaledAdd(due_j[top_dbo->wrt],-bo_ij->BO*bo_ij->A2_ji, dBOp); + + if ( nbr_l->nbr == i ) + { + rvec_Copy( dDeltap_self, workspace->dDeltap_self[i] ); + + /* dBO */ + rvec_ScaledAdd( top_dbo->dBO, bo_ij->C1dbo, bo_ij->dBOp ); //1st + rvec_ScaledAdd( top_dbo->dBO, bo_ij->C2dbo, dDeltap_self ); //2nd + + /* dBOpi */ + rvec_ScaledAdd(top_dbo->dBOpi, bo_ij->C1dbopi, bo_ij->dln_BOp_pi); //1 + rvec_ScaledAdd(top_dbo->dBOpi, bo_ij->C2dbopi, bo_ij->dBOp); //2nd + rvec_ScaledAdd(top_dbo->dBOpi, bo_ij->C3dbopi, dDeltap_self); //3rd + + /* dBOpp, 1st */ + rvec_ScaledAdd(top_dbo->dBOpi2, bo_ij->C1dbopi2, bo_ij->dln_BOp_pi2); + rvec_ScaledAdd(top_dbo->dBOpi2, bo_ij->C2dbopi2, bo_ij->dBOp); //2nd + rvec_ScaledAdd(top_dbo->dBOpi2, bo_ij->C3dbopi2, dDeltap_self); //3rd + + /* do the adjustments on i */ + //rvec_ScaledAdd( due_i[i], + //bo_ij->A0_ij + bo_ij->BO * bo_ij->A1_ij, bo_ij->dBOp );//1st,dBO + //rvec_ScaledAdd( due_i[i], bo_ij->BO * bo_ij->A2_ij, + //dDeltap_self ); //2nd, dBO + } + + //rvec_Add( workspace->dDelta[nbr_l->nbr], top_dbo->dBO ); + ++(*top), ++top_dbo; + } + + /* Now we are processing neighbor k of i. */ + top_dbo->wrt = nbr_k->nbr; + rvec_Copy( dBOp, nbr_k->bo_data.dBOp ); + + rvec_Scale( top_dbo->dBO, -bo_ij->C2dbo, dBOp ); //dBO-2 + rvec_Scale( top_dbo->dBOpi, -bo_ij->C3dbopi, dBOp ); //dBOpi-3 + rvec_Scale( top_dbo->dBOpi2, -bo_ij->C3dbopi2, dBOp );//dBOpp-3 + //rvec_ScaledAdd(due_i[top_dbo->wrt],-bo_ij->BO*bo_ij->A2_ij,dBOp);//dBO-2 + + // fprintf( stderr, "\tnbr_k = %d, nbr_l = %d, l = %d, end_j = %d\n", + // workspace->orig_id[nbr_k->nbr], + // workspace->orig_id[bonds->select.bond_list[l].nbr], l, end_j ); + + if ( l < end_j && bonds->select.bond_list[l].nbr == nbr_k->nbr ) + { + /* This is a common neighbor of i and j. */ + nbr_l = &(bonds->select.bond_list[l]); + rvec_Copy( dBOp, nbr_l->bo_data.dBOp ); + + rvec_ScaledAdd( top_dbo->dBO, -bo_ij->C3dbo, dBOp ); //dBO,3rd + rvec_ScaledAdd( top_dbo->dBOpi, -bo_ij->C4dbopi, dBOp ); //dBOpi,4th + rvec_ScaledAdd( top_dbo->dBOpi2, -bo_ij->C4dbopi2, dBOp );//dBOpp.4th + ++l; + + //rvec_ScaledAdd( due_j[top_dbo->wrt], -bo_ij->BO * bo_ij->A2_ji, + //nbr_l->bo_data.dBOp ); //3rd, dBO + } + else if ( k == pj ) + { + /* This negihbor is j. */ + rvec_Copy( dDeltap_self, workspace->dDeltap_self[j] ); + + rvec_ScaledAdd( top_dbo->dBO, -bo_ij->C1dbo, bo_ij->dBOp );// 1st, dBO + rvec_ScaledAdd( top_dbo->dBO, bo_ij->C3dbo, dDeltap_self );// 3rd, dBO + + /* dBOpi, 1st */ + rvec_ScaledAdd(top_dbo->dBOpi, -bo_ij->C1dbopi, bo_ij->dln_BOp_pi); + rvec_ScaledAdd(top_dbo->dBOpi, -bo_ij->C2dbopi, bo_ij->dBOp); //2nd + rvec_ScaledAdd( top_dbo->dBOpi, bo_ij->C4dbopi, dDeltap_self ); //4th + + /* dBOpi2, 1st */ + rvec_ScaledAdd(top_dbo->dBOpi2, -bo_ij->C1dbopi2, bo_ij->dln_BOp_pi2 ); + rvec_ScaledAdd(top_dbo->dBOpi2, -bo_ij->C2dbopi2, bo_ij->dBOp ); //2nd + rvec_ScaledAdd(top_dbo->dBOpi2, bo_ij->C4dbopi2, dDeltap_self ); //4th + + //rvec_ScaledAdd( due_j[j], -(bo_ij->A0_ij + bo_ij->BO*bo_ij->A1_ij), + //bo_ij->dBOp ); //1st, dBO + //rvec_ScaledAdd( due_j[j], bo_ij->BO * bo_ij->A2_ji, + //workspace->dDeltap_self[j] ); //3rd, dBO + } + + // rvec_Add( workspace->dDelta[nbr_k->nbr], top_dbo->dBO ); + ++(*top), ++top_dbo; } - - // rvec_Add( workspace->dDelta[nbr_k->nbr], top_dbo->dBO ); - ++(*top), ++top_dbo; - } - - for( ; l < end_j; ++l ) { - /* These are the remaining neighbors of j which are not in the - neighbor_list of i. Note that they might also include i!*/ - nbr_l = &(bonds->select.bond_list[l]); - top_dbo->wrt = nbr_l->nbr; - rvec_Copy( dBOp, nbr_l->bo_data.dBOp ); - //fprintf( stderr,"\tl=%d, nbr_l=%d\n",l,workspace->orig_id[nbr_l->nbr] ); - - rvec_Scale( top_dbo->dBO, -bo_ij->C3dbo, dBOp ); //3rd, dBO - rvec_Scale( top_dbo->dBOpi, -bo_ij->C4dbopi, dBOp ); //4th, dBOpi - rvec_Scale( top_dbo->dBOpi2, -bo_ij->C4dbopi2, dBOp );//4th, dBOpp - - // rvec_ScaledAdd( due_j[top_dbo->wrt], -bo_ij->BO * bo_ij->A2_ji, - // nbr_l->bo_data.dBOp ); - - if( nbr_l->nbr == i ) { - /* do the adjustments on i */ - rvec_Copy( dDeltap_self, workspace->dDeltap_self[i] ); - - /* dBO, 1st */ - rvec_ScaledAdd( top_dbo->dBO, bo_ij->C1dbo, bo_ij->dBOp ); - rvec_ScaledAdd( top_dbo->dBO, bo_ij->C2dbo, dDeltap_self ); //2nd, dBO - - /* dBOpi, 1st */ - rvec_ScaledAdd( top_dbo->dBOpi, bo_ij->C1dbopi, bo_ij->dln_BOp_pi ); - rvec_ScaledAdd( top_dbo->dBOpi, bo_ij->C2dbopi, bo_ij->dBOp ); //2nd - rvec_ScaledAdd( top_dbo->dBOpi, bo_ij->C3dbopi, dDeltap_self ); //3rd - - /* dBOpipi, 1st */ - rvec_ScaledAdd(top_dbo->dBOpi2, bo_ij->C1dbopi2, bo_ij->dln_BOp_pi2); - rvec_ScaledAdd( top_dbo->dBOpi2, bo_ij->C2dbopi2, bo_ij->dBOp ); //2nd - rvec_ScaledAdd( top_dbo->dBOpi2, bo_ij->C3dbopi2, dDeltap_self );//3rd - - //rvec_ScaledAdd( due_i[i], bo_ij->A0_ij + bo_ij->BO * bo_ij->A1_ij, - //bo_ij->dBOp ); /*1st, dBO*/ - //rvec_ScaledAdd( due_i[i], bo_ij->BO * bo_ij->A2_ij, - //dDeltap_self ); /*2nd, dBO*/ + + for ( ; l < end_j; ++l ) + { + /* These are the remaining neighbors of j which are not in the + neighbor_list of i. Note that they might also include i!*/ + nbr_l = &(bonds->select.bond_list[l]); + top_dbo->wrt = nbr_l->nbr; + rvec_Copy( dBOp, nbr_l->bo_data.dBOp ); + //fprintf( stderr,"\tl=%d, nbr_l=%d\n",l,workspace->orig_id[nbr_l->nbr] ); + + rvec_Scale( top_dbo->dBO, -bo_ij->C3dbo, dBOp ); //3rd, dBO + rvec_Scale( top_dbo->dBOpi, -bo_ij->C4dbopi, dBOp ); //4th, dBOpi + rvec_Scale( top_dbo->dBOpi2, -bo_ij->C4dbopi2, dBOp );//4th, dBOpp + + // rvec_ScaledAdd( due_j[top_dbo->wrt], -bo_ij->BO * bo_ij->A2_ji, + // nbr_l->bo_data.dBOp ); + + if ( nbr_l->nbr == i ) + { + /* do the adjustments on i */ + rvec_Copy( dDeltap_self, workspace->dDeltap_self[i] ); + + /* dBO, 1st */ + rvec_ScaledAdd( top_dbo->dBO, bo_ij->C1dbo, bo_ij->dBOp ); + rvec_ScaledAdd( top_dbo->dBO, bo_ij->C2dbo, dDeltap_self ); //2nd, dBO + + /* dBOpi, 1st */ + rvec_ScaledAdd( top_dbo->dBOpi, bo_ij->C1dbopi, bo_ij->dln_BOp_pi ); + rvec_ScaledAdd( top_dbo->dBOpi, bo_ij->C2dbopi, bo_ij->dBOp ); //2nd + rvec_ScaledAdd( top_dbo->dBOpi, bo_ij->C3dbopi, dDeltap_self ); //3rd + + /* dBOpipi, 1st */ + rvec_ScaledAdd(top_dbo->dBOpi2, bo_ij->C1dbopi2, bo_ij->dln_BOp_pi2); + rvec_ScaledAdd( top_dbo->dBOpi2, bo_ij->C2dbopi2, bo_ij->dBOp ); //2nd + rvec_ScaledAdd( top_dbo->dBOpi2, bo_ij->C3dbopi2, dDeltap_self );//3rd + + //rvec_ScaledAdd( due_i[i], bo_ij->A0_ij + bo_ij->BO * bo_ij->A1_ij, + //bo_ij->dBOp ); /*1st, dBO*/ + //rvec_ScaledAdd( due_i[i], bo_ij->BO * bo_ij->A2_ij, + //dDeltap_self ); /*2nd, dBO*/ + } + + // rvec_Add( workspace->dDelta[nbr_l->nbr], top_dbo->dBO ); + ++(*top), ++top_dbo; } - // rvec_Add( workspace->dDelta[nbr_l->nbr], top_dbo->dBO ); - ++(*top), ++top_dbo; - } - - /*for( k = 0; k < 21; ++k ){ - fprintf( stderr, "%d %d %d, due_i:[%g %g %g]\n", - i+1, j+1, k+1, due_i[k][0], due_i[k][1], due_i[k][2] ); - fprintf( stderr, "%d %d %d, due_j:[%g %g %g]\n", - i+1, j+1, k+1, due_j[k][0], due_j[k][1], due_j[k][2] ); - }*/ + /*for( k = 0; k < 21; ++k ){ + fprintf( stderr, "%d %d %d, due_i:[%g %g %g]\n", + i+1, j+1, k+1, due_i[k][0], due_i[k][1], due_i[k][2] ); + fprintf( stderr, "%d %d %d, due_j:[%g %g %g]\n", + i+1, j+1, k+1, due_j[k][0], due_j[k][1], due_j[k][2] ); + }*/ } #endif -void Add_dBond_to_Forces_NPT( int i, int pj, reax_system *system, - simulation_data *data, static_storage *workspace, - list **lists ) +void Add_dBond_to_Forces_NPT( int i, int pj, reax_system *system, + simulation_data *data, static_storage *workspace, + list **lists ) { - list *bonds = (*lists) + BONDS; - bond_data *nbr_j, *nbr_k; - bond_order_data *bo_ij, *bo_ji; - dbond_coefficients coef; - rvec temp, ext_press; - ivec rel_box; - int pk, k, j; - - /* Initializations */ - nbr_j = &(bonds->select.bond_list[pj]); - j = nbr_j->nbr; - bo_ij = &(nbr_j->bo_data); - bo_ji = &(bonds->select.bond_list[ nbr_j->sym_index ].bo_data); - - coef.C1dbo = bo_ij->C1dbo * (bo_ij->Cdbo + bo_ji->Cdbo); - coef.C2dbo = bo_ij->C2dbo * (bo_ij->Cdbo + bo_ji->Cdbo); - coef.C3dbo = bo_ij->C3dbo * (bo_ij->Cdbo + bo_ji->Cdbo); - - coef.C1dbopi = bo_ij->C1dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); - coef.C2dbopi = bo_ij->C2dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); - coef.C3dbopi = bo_ij->C3dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); - coef.C4dbopi = bo_ij->C4dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); - - coef.C1dbopi2 = bo_ij->C1dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); - coef.C2dbopi2 = bo_ij->C2dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); - coef.C3dbopi2 = bo_ij->C3dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); - coef.C4dbopi2 = bo_ij->C4dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); - - coef.C1dDelta = bo_ij->C1dbo * (workspace->CdDelta[i]+workspace->CdDelta[j]); - coef.C2dDelta = bo_ij->C2dbo * (workspace->CdDelta[i]+workspace->CdDelta[j]); - coef.C3dDelta = bo_ij->C3dbo * (workspace->CdDelta[i]+workspace->CdDelta[j]); - - - /************************************ - * forces related to atom i * - * first neighbors of atom i * - ************************************/ - for( pk = Start_Index(i, bonds); pk < End_Index(i, bonds); ++pk ) { - nbr_k = &(bonds->select.bond_list[pk]); - k = nbr_k->nbr; - - rvec_Scale( temp, -coef.C2dbo, nbr_k->bo_data.dBOp ); /*2nd,dBO*/ - rvec_ScaledAdd( temp, -coef.C2dDelta, nbr_k->bo_data.dBOp );/*dDelta*/ - rvec_ScaledAdd( temp, -coef.C3dbopi, nbr_k->bo_data.dBOp ); /*3rd,dBOpi*/ - rvec_ScaledAdd( temp, -coef.C3dbopi2, nbr_k->bo_data.dBOp );/*3rd,dBOpi2*/ - + list *bonds = (*lists) + BONDS; + bond_data *nbr_j, *nbr_k; + bond_order_data *bo_ij, *bo_ji; + dbond_coefficients coef; + rvec temp, ext_press; + ivec rel_box; + int pk, k, j; + + /* Initializations */ + nbr_j = &(bonds->select.bond_list[pj]); + j = nbr_j->nbr; + bo_ij = &(nbr_j->bo_data); + bo_ji = &(bonds->select.bond_list[ nbr_j->sym_index ].bo_data); + + coef.C1dbo = bo_ij->C1dbo * (bo_ij->Cdbo + bo_ji->Cdbo); + coef.C2dbo = bo_ij->C2dbo * (bo_ij->Cdbo + bo_ji->Cdbo); + coef.C3dbo = bo_ij->C3dbo * (bo_ij->Cdbo + bo_ji->Cdbo); + + coef.C1dbopi = bo_ij->C1dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); + coef.C2dbopi = bo_ij->C2dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); + coef.C3dbopi = bo_ij->C3dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); + coef.C4dbopi = bo_ij->C4dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); + + coef.C1dbopi2 = bo_ij->C1dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); + coef.C2dbopi2 = bo_ij->C2dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); + coef.C3dbopi2 = bo_ij->C3dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); + coef.C4dbopi2 = bo_ij->C4dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); + + coef.C1dDelta = bo_ij->C1dbo * (workspace->CdDelta[i] + workspace->CdDelta[j]); + coef.C2dDelta = bo_ij->C2dbo * (workspace->CdDelta[i] + workspace->CdDelta[j]); + coef.C3dDelta = bo_ij->C3dbo * (workspace->CdDelta[i] + workspace->CdDelta[j]); + + + /************************************ + * forces related to atom i * + * first neighbors of atom i * + ************************************/ + for ( pk = Start_Index(i, bonds); pk < End_Index(i, bonds); ++pk ) + { + nbr_k = &(bonds->select.bond_list[pk]); + k = nbr_k->nbr; + + rvec_Scale( temp, -coef.C2dbo, nbr_k->bo_data.dBOp ); /*2nd,dBO*/ + rvec_ScaledAdd( temp, -coef.C2dDelta, nbr_k->bo_data.dBOp );/*dDelta*/ + rvec_ScaledAdd( temp, -coef.C3dbopi, nbr_k->bo_data.dBOp ); /*3rd,dBOpi*/ + rvec_ScaledAdd( temp, -coef.C3dbopi2, nbr_k->bo_data.dBOp );/*3rd,dBOpi2*/ + + /* force */ + rvec_Add( system->atoms[k].f, temp ); + /* pressure */ + rvec_iMultiply( ext_press, nbr_k->rel_box, temp ); + rvec_Add( data->ext_press, ext_press ); + + /* if( !ivec_isZero( nbr_k->rel_box ) ) + fprintf( stderr, "%3d %3d %3d: dvec[%10.6f %10.6f %10.6f] + ext[%3d %3d %3d] f[%10.6f %10.6f %10.6f]\n", + i+1, + system->atoms[i].x[0],system->atoms[i].x[1],system->atoms[i].x[2], + j+1, k+1, + system->atoms[k].x[0], system->atoms[k].x[1], system->atoms[k].x[2], + nbr_k->dvec[0], nbr_k->dvec[1], nbr_k->dvec[2], + nbr_k->rel_box[0], nbr_k->rel_box[1], nbr_k->rel_box[2], + temp[0], temp[1], temp[2] ); */ + } + + /* then atom i itself */ + rvec_Scale( temp, coef.C1dbo, bo_ij->dBOp ); /*1st, dBO*/ + rvec_ScaledAdd( temp, coef.C2dbo, workspace->dDeltap_self[i] ); /*2nd, dBO*/ + + rvec_ScaledAdd( temp, coef.C1dDelta, bo_ij->dBOp ); /*1st, dBO*/ + rvec_ScaledAdd( temp, coef.C2dDelta, workspace->dDeltap_self[i] );/*2nd, dBO*/ + + rvec_ScaledAdd( temp, coef.C1dbopi, bo_ij->dln_BOp_pi ); /*1st,dBOpi*/ + rvec_ScaledAdd( temp, coef.C2dbopi, bo_ij->dBOp ); /*2nd,dBOpi*/ + rvec_ScaledAdd( temp, coef.C3dbopi, workspace->dDeltap_self[i] );/*3rd,dBOpi*/ + + rvec_ScaledAdd(temp, coef.C1dbopi2, bo_ij->dln_BOp_pi2) ; /*1st,dBO_pi2*/ + rvec_ScaledAdd(temp, coef.C2dbopi2, bo_ij->dBOp); /*2nd,dBO_pi2*/ + rvec_ScaledAdd(temp, coef.C3dbopi2, workspace->dDeltap_self[i]);/*3rd,dBO_pi2*/ + /* force */ - rvec_Add( system->atoms[k].f, temp ); + rvec_Add( system->atoms[i].f, temp ); + /* ext pressure due to i dropped, counting force on j only will be enough */ + + + /**************************************************************************** + * forces and pressure related to atom j * + * first neighbors of atom j * + ***************************************************************************/ + for ( pk = Start_Index(j, bonds); pk < End_Index(j, bonds); ++pk ) + { + nbr_k = &(bonds->select.bond_list[pk]); + k = nbr_k->nbr; + + rvec_Scale( temp, -coef.C3dbo, nbr_k->bo_data.dBOp ); /*3rd,dBO*/ + rvec_ScaledAdd( temp, -coef.C3dDelta, nbr_k->bo_data.dBOp );/*dDelta*/ + rvec_ScaledAdd( temp, -coef.C4dbopi, nbr_k->bo_data.dBOp ); /*4th,dBOpi*/ + rvec_ScaledAdd( temp, -coef.C4dbopi2, nbr_k->bo_data.dBOp );/*4th,dBOpi2*/ + + /* force */ + rvec_Add( system->atoms[k].f, temp ); + /* pressure */ + if ( k != i ) + { + ivec_Sum(rel_box, nbr_k->rel_box, nbr_j->rel_box);//k's rel_box wrt i + rvec_iMultiply( ext_press, rel_box, temp ); + rvec_Add( data->ext_press, ext_press ); + + /* if( !ivec_isZero( rel_box ) ) + fprintf( stderr, "%3d %3d %3d: dvec[%10.6f %10.6f %10.6f] + ext[%3d %3d %3d] f[%10.6f %10.6f %10.6f]\n", + i+1, j+1, + system->atoms[j].x[0],system->atoms[j].x[1],system->atoms[j].x[2], + k+1, + system->atoms[k].x[0], system->atoms[k].x[1], system->atoms[k].x[2], + nbr_k->dvec[0], nbr_k->dvec[1], nbr_k->dvec[2], + rel_box[0], rel_box[1], rel_box[2], + temp[0], temp[1], temp[2] ); */ + } + } + + /* then atom j itself */ + rvec_Scale( temp, -coef.C1dbo, bo_ij->dBOp ); /*1st, dBO*/ + rvec_ScaledAdd( temp, coef.C3dbo, workspace->dDeltap_self[j] ); /*2nd, dBO*/ + + rvec_ScaledAdd( temp, -coef.C1dDelta, bo_ij->dBOp ); /*1st, dBO*/ + rvec_ScaledAdd( temp, coef.C3dDelta, workspace->dDeltap_self[j] );/*2nd, dBO*/ + + rvec_ScaledAdd( temp, -coef.C1dbopi, bo_ij->dln_BOp_pi ); /*1st,dBOpi*/ + rvec_ScaledAdd( temp, -coef.C2dbopi, bo_ij->dBOp ); /*2nd,dBOpi*/ + rvec_ScaledAdd( temp, coef.C4dbopi, workspace->dDeltap_self[j] );/*3rd,dBOpi*/ + + rvec_ScaledAdd(temp, -coef.C1dbopi2, bo_ij->dln_BOp_pi2); /*1st,dBOpi2*/ + rvec_ScaledAdd(temp, -coef.C2dbopi2, bo_ij->dBOp); /*2nd,dBOpi2*/ + rvec_ScaledAdd(temp, coef.C4dbopi2, workspace->dDeltap_self[j]);/*3rd,dBOpi2*/ + + /* force */ + rvec_Add( system->atoms[j].f, temp ); /* pressure */ - rvec_iMultiply( ext_press, nbr_k->rel_box, temp ); + rvec_iMultiply( ext_press, nbr_j->rel_box, temp ); rvec_Add( data->ext_press, ext_press ); - - /* if( !ivec_isZero( nbr_k->rel_box ) ) - fprintf( stderr, "%3d %3d %3d: dvec[%10.6f %10.6f %10.6f] + + /* if( !ivec_isZero( nbr_j->rel_box ) ) + fprintf( stderr, "%3d %3d %3d: dvec[%10.6f %10.6f %10.6f] ext[%3d %3d %3d] f[%10.6f %10.6f %10.6f]\n", - i+1, - system->atoms[i].x[0],system->atoms[i].x[1],system->atoms[i].x[2], - j+1, k+1, - system->atoms[k].x[0], system->atoms[k].x[1], system->atoms[k].x[2], - nbr_k->dvec[0], nbr_k->dvec[1], nbr_k->dvec[2], - nbr_k->rel_box[0], nbr_k->rel_box[1], nbr_k->rel_box[2], + i+1, system->atoms[i].x[0], system->atoms[i].x[1], system->atoms[i].x[2], + j+1, system->atoms[j].x[0], system->atoms[j].x[1], system->atoms[j].x[2], + j+1, nbr_j->dvec[0], nbr_j->dvec[1], nbr_j->dvec[2], + nbr_j->rel_box[0], nbr_j->rel_box[1], nbr_j->rel_box[2], temp[0], temp[1], temp[2] ); */ - } - - /* then atom i itself */ - rvec_Scale( temp, coef.C1dbo, bo_ij->dBOp ); /*1st, dBO*/ - rvec_ScaledAdd( temp, coef.C2dbo, workspace->dDeltap_self[i] ); /*2nd, dBO*/ - - rvec_ScaledAdd( temp, coef.C1dDelta, bo_ij->dBOp ); /*1st, dBO*/ - rvec_ScaledAdd( temp, coef.C2dDelta, workspace->dDeltap_self[i] );/*2nd, dBO*/ - - rvec_ScaledAdd( temp, coef.C1dbopi, bo_ij->dln_BOp_pi ); /*1st,dBOpi*/ - rvec_ScaledAdd( temp, coef.C2dbopi, bo_ij->dBOp ); /*2nd,dBOpi*/ - rvec_ScaledAdd( temp, coef.C3dbopi, workspace->dDeltap_self[i] );/*3rd,dBOpi*/ - - rvec_ScaledAdd(temp, coef.C1dbopi2, bo_ij->dln_BOp_pi2) ; /*1st,dBO_pi2*/ - rvec_ScaledAdd(temp, coef.C2dbopi2, bo_ij->dBOp); /*2nd,dBO_pi2*/ - rvec_ScaledAdd(temp, coef.C3dbopi2, workspace->dDeltap_self[i]);/*3rd,dBO_pi2*/ - - /* force */ - rvec_Add( system->atoms[i].f, temp ); - /* ext pressure due to i dropped, counting force on j only will be enough */ - - - /**************************************************************************** - * forces and pressure related to atom j * - * first neighbors of atom j * - ***************************************************************************/ - for( pk = Start_Index(j, bonds); pk < End_Index(j, bonds); ++pk ) { - nbr_k = &(bonds->select.bond_list[pk]); - k = nbr_k->nbr; - - rvec_Scale( temp, -coef.C3dbo, nbr_k->bo_data.dBOp ); /*3rd,dBO*/ - rvec_ScaledAdd( temp, -coef.C3dDelta, nbr_k->bo_data.dBOp );/*dDelta*/ - rvec_ScaledAdd( temp, -coef.C4dbopi, nbr_k->bo_data.dBOp ); /*4th,dBOpi*/ - rvec_ScaledAdd( temp, -coef.C4dbopi2, nbr_k->bo_data.dBOp );/*4th,dBOpi2*/ - - /* force */ - rvec_Add( system->atoms[k].f, temp ); - /* pressure */ - if( k != i ) { - ivec_Sum(rel_box, nbr_k->rel_box, nbr_j->rel_box);//k's rel_box wrt i - rvec_iMultiply( ext_press, rel_box, temp ); - rvec_Add( data->ext_press, ext_press ); - - /* if( !ivec_isZero( rel_box ) ) - fprintf( stderr, "%3d %3d %3d: dvec[%10.6f %10.6f %10.6f] - ext[%3d %3d %3d] f[%10.6f %10.6f %10.6f]\n", - i+1, j+1, - system->atoms[j].x[0],system->atoms[j].x[1],system->atoms[j].x[2], - k+1, - system->atoms[k].x[0], system->atoms[k].x[1], system->atoms[k].x[2], - nbr_k->dvec[0], nbr_k->dvec[1], nbr_k->dvec[2], - rel_box[0], rel_box[1], rel_box[2], - temp[0], temp[1], temp[2] ); */ - } - } - - /* then atom j itself */ - rvec_Scale( temp, -coef.C1dbo, bo_ij->dBOp ); /*1st, dBO*/ - rvec_ScaledAdd( temp, coef.C3dbo, workspace->dDeltap_self[j] ); /*2nd, dBO*/ - - rvec_ScaledAdd( temp, -coef.C1dDelta, bo_ij->dBOp ); /*1st, dBO*/ - rvec_ScaledAdd( temp, coef.C3dDelta, workspace->dDeltap_self[j] );/*2nd, dBO*/ - - rvec_ScaledAdd( temp, -coef.C1dbopi, bo_ij->dln_BOp_pi ); /*1st,dBOpi*/ - rvec_ScaledAdd( temp, -coef.C2dbopi, bo_ij->dBOp ); /*2nd,dBOpi*/ - rvec_ScaledAdd( temp, coef.C4dbopi, workspace->dDeltap_self[j] );/*3rd,dBOpi*/ - - rvec_ScaledAdd(temp, -coef.C1dbopi2, bo_ij->dln_BOp_pi2); /*1st,dBOpi2*/ - rvec_ScaledAdd(temp, -coef.C2dbopi2, bo_ij->dBOp); /*2nd,dBOpi2*/ - rvec_ScaledAdd(temp, coef.C4dbopi2, workspace->dDeltap_self[j]);/*3rd,dBOpi2*/ - - /* force */ - rvec_Add( system->atoms[j].f, temp ); - /* pressure */ - rvec_iMultiply( ext_press, nbr_j->rel_box, temp ); - rvec_Add( data->ext_press, ext_press ); - - /* if( !ivec_isZero( nbr_j->rel_box ) ) - fprintf( stderr, "%3d %3d %3d: dvec[%10.6f %10.6f %10.6f] - ext[%3d %3d %3d] f[%10.6f %10.6f %10.6f]\n", - i+1, system->atoms[i].x[0], system->atoms[i].x[1], system->atoms[i].x[2], - j+1, system->atoms[j].x[0], system->atoms[j].x[1], system->atoms[j].x[2], - j+1, nbr_j->dvec[0], nbr_j->dvec[1], nbr_j->dvec[2], - nbr_j->rel_box[0], nbr_j->rel_box[1], nbr_j->rel_box[2], - temp[0], temp[1], temp[2] ); */ } -void Add_dBond_to_Forces( int i, int pj, reax_system *system, - simulation_data *data, static_storage *workspace, - list **lists ) +void Add_dBond_to_Forces( int i, int pj, reax_system *system, + simulation_data *data, static_storage *workspace, + list **lists ) { - list *bonds = (*lists) + BONDS; - bond_data *nbr_j, *nbr_k; - bond_order_data *bo_ij, *bo_ji; - dbond_coefficients coef; - int pk, k, j; - - /* Initializations */ - nbr_j = &(bonds->select.bond_list[pj]); - j = nbr_j->nbr; - bo_ij = &(nbr_j->bo_data); - bo_ji = &(bonds->select.bond_list[ nbr_j->sym_index ].bo_data); - - coef.C1dbo = bo_ij->C1dbo * (bo_ij->Cdbo + bo_ji->Cdbo); - coef.C2dbo = bo_ij->C2dbo * (bo_ij->Cdbo + bo_ji->Cdbo); - coef.C3dbo = bo_ij->C3dbo * (bo_ij->Cdbo + bo_ji->Cdbo); - - coef.C1dbopi = bo_ij->C1dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); - coef.C2dbopi = bo_ij->C2dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); - coef.C3dbopi = bo_ij->C3dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); - coef.C4dbopi = bo_ij->C4dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); - - coef.C1dbopi2 = bo_ij->C1dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); - coef.C2dbopi2 = bo_ij->C2dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); - coef.C3dbopi2 = bo_ij->C3dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); - coef.C4dbopi2 = bo_ij->C4dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); - - coef.C1dDelta = bo_ij->C1dbo * (workspace->CdDelta[i]+workspace->CdDelta[j]); - coef.C2dDelta = bo_ij->C2dbo * (workspace->CdDelta[i]+workspace->CdDelta[j]); - coef.C3dDelta = bo_ij->C3dbo * (workspace->CdDelta[i]+workspace->CdDelta[j]); - - for( pk = Start_Index(i, bonds); pk < End_Index(i, bonds); ++pk ) { - nbr_k = &(bonds->select.bond_list[pk]); - k = nbr_k->nbr; - - rvec_ScaledAdd( system->atoms[k].f, -coef.C2dbo, nbr_k->bo_data.dBOp ); + list *bonds = (*lists) + BONDS; + bond_data *nbr_j, *nbr_k; + bond_order_data *bo_ij, *bo_ji; + dbond_coefficients coef; + int pk, k, j; + + /* Initializations */ + nbr_j = &(bonds->select.bond_list[pj]); + j = nbr_j->nbr; + bo_ij = &(nbr_j->bo_data); + bo_ji = &(bonds->select.bond_list[ nbr_j->sym_index ].bo_data); + + coef.C1dbo = bo_ij->C1dbo * (bo_ij->Cdbo + bo_ji->Cdbo); + coef.C2dbo = bo_ij->C2dbo * (bo_ij->Cdbo + bo_ji->Cdbo); + coef.C3dbo = bo_ij->C3dbo * (bo_ij->Cdbo + bo_ji->Cdbo); + + coef.C1dbopi = bo_ij->C1dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); + coef.C2dbopi = bo_ij->C2dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); + coef.C3dbopi = bo_ij->C3dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); + coef.C4dbopi = bo_ij->C4dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); + + coef.C1dbopi2 = bo_ij->C1dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); + coef.C2dbopi2 = bo_ij->C2dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); + coef.C3dbopi2 = bo_ij->C3dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); + coef.C4dbopi2 = bo_ij->C4dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); + + coef.C1dDelta = bo_ij->C1dbo * (workspace->CdDelta[i] + workspace->CdDelta[j]); + coef.C2dDelta = bo_ij->C2dbo * (workspace->CdDelta[i] + workspace->CdDelta[j]); + coef.C3dDelta = bo_ij->C3dbo * (workspace->CdDelta[i] + workspace->CdDelta[j]); + + for ( pk = Start_Index(i, bonds); pk < End_Index(i, bonds); ++pk ) + { + nbr_k = &(bonds->select.bond_list[pk]); + k = nbr_k->nbr; + + rvec_ScaledAdd( system->atoms[k].f, -coef.C2dbo, nbr_k->bo_data.dBOp ); + /*2nd, dBO*/ + rvec_ScaledAdd( system->atoms[k].f, -coef.C2dDelta, nbr_k->bo_data.dBOp ); + /*dDelta*/ + rvec_ScaledAdd( system->atoms[k].f, -coef.C3dbopi, nbr_k->bo_data.dBOp ); + /*3rd, dBOpi*/ + rvec_ScaledAdd( system->atoms[k].f, -coef.C3dbopi2, nbr_k->bo_data.dBOp ); + /*3rd, dBOpi2*/ + } + + rvec_ScaledAdd( system->atoms[i].f, coef.C1dbo, bo_ij->dBOp ); + /*1st, dBO*/ + rvec_ScaledAdd( system->atoms[i].f, coef.C2dbo, workspace->dDeltap_self[i] ); + /*2nd, dBO*/ + + rvec_ScaledAdd(system->atoms[i].f, coef.C1dDelta, bo_ij->dBOp); + /*1st, dBO*/ + rvec_ScaledAdd(system->atoms[i].f, coef.C2dDelta, workspace->dDeltap_self[i]); + /*2nd, dBO*/ + + rvec_ScaledAdd( system->atoms[i].f, coef.C1dbopi, bo_ij->dln_BOp_pi ); + /*1st, dBOpi*/ + rvec_ScaledAdd( system->atoms[i].f, coef.C2dbopi, bo_ij->dBOp ); + /*2nd, dBOpi*/ + rvec_ScaledAdd(system->atoms[i].f, coef.C3dbopi, workspace->dDeltap_self[i]); + /*3rd, dBOpi*/ + + rvec_ScaledAdd( system->atoms[i].f, coef.C1dbopi2, bo_ij->dln_BOp_pi2 ); + /*1st, dBO_pi2*/ + rvec_ScaledAdd( system->atoms[i].f, coef.C2dbopi2, bo_ij->dBOp ); + /*2nd, dBO_pi2*/ + rvec_ScaledAdd(system->atoms[i].f, coef.C3dbopi2, workspace->dDeltap_self[i]); + /*3rd, dBO_pi2*/ + + + for ( pk = Start_Index(j, bonds); pk < End_Index(j, bonds); ++pk ) + { + nbr_k = &(bonds->select.bond_list[pk]); + k = nbr_k->nbr; + + rvec_ScaledAdd( system->atoms[k].f, -coef.C3dbo, nbr_k->bo_data.dBOp ); + /*3rd, dBO*/ + rvec_ScaledAdd( system->atoms[k].f, -coef.C3dDelta, nbr_k->bo_data.dBOp ); + /*dDelta*/ + rvec_ScaledAdd( system->atoms[k].f, -coef.C4dbopi, nbr_k->bo_data.dBOp ); + /*4th, dBOpi*/ + rvec_ScaledAdd( system->atoms[k].f, -coef.C4dbopi2, nbr_k->bo_data.dBOp ); + /*4th, dBOpi2*/ + } + + rvec_ScaledAdd( system->atoms[j].f, -coef.C1dbo, bo_ij->dBOp ); + /*1st, dBO*/ + rvec_ScaledAdd( system->atoms[j].f, coef.C3dbo, workspace->dDeltap_self[j] ); /*2nd, dBO*/ - rvec_ScaledAdd( system->atoms[k].f, -coef.C2dDelta, nbr_k->bo_data.dBOp ); - /*dDelta*/ - rvec_ScaledAdd( system->atoms[k].f, -coef.C3dbopi, nbr_k->bo_data.dBOp ); + + rvec_ScaledAdd( system->atoms[j].f, -coef.C1dDelta, bo_ij->dBOp ); + /*1st, dBO*/ + rvec_ScaledAdd(system->atoms[j].f, coef.C3dDelta, workspace->dDeltap_self[j]); + /*2nd, dBO*/ + + rvec_ScaledAdd( system->atoms[j].f, -coef.C1dbopi, bo_ij->dln_BOp_pi ); + /*1st, dBOpi*/ + rvec_ScaledAdd( system->atoms[j].f, -coef.C2dbopi, bo_ij->dBOp ); + /*2nd, dBOpi*/ + rvec_ScaledAdd(system->atoms[j].f, coef.C4dbopi, workspace->dDeltap_self[j]); /*3rd, dBOpi*/ - rvec_ScaledAdd( system->atoms[k].f, -coef.C3dbopi2, nbr_k->bo_data.dBOp ); + + rvec_ScaledAdd( system->atoms[j].f, -coef.C1dbopi2, bo_ij->dln_BOp_pi2 ); + /*1st, dBOpi2*/ + rvec_ScaledAdd( system->atoms[j].f, -coef.C2dbopi2, bo_ij->dBOp ); + /*2nd, dBOpi2*/ + rvec_ScaledAdd(system->atoms[j].f, coef.C4dbopi2, workspace->dDeltap_self[j]); /*3rd, dBOpi2*/ - } - - rvec_ScaledAdd( system->atoms[i].f, coef.C1dbo, bo_ij->dBOp ); - /*1st, dBO*/ - rvec_ScaledAdd( system->atoms[i].f, coef.C2dbo, workspace->dDeltap_self[i] ); - /*2nd, dBO*/ - - rvec_ScaledAdd(system->atoms[i].f, coef.C1dDelta, bo_ij->dBOp); - /*1st, dBO*/ - rvec_ScaledAdd(system->atoms[i].f, coef.C2dDelta, workspace->dDeltap_self[i]); - /*2nd, dBO*/ - - rvec_ScaledAdd( system->atoms[i].f, coef.C1dbopi, bo_ij->dln_BOp_pi ); - /*1st, dBOpi*/ - rvec_ScaledAdd( system->atoms[i].f, coef.C2dbopi, bo_ij->dBOp ); - /*2nd, dBOpi*/ - rvec_ScaledAdd(system->atoms[i].f, coef.C3dbopi, workspace->dDeltap_self[i]); - /*3rd, dBOpi*/ - - rvec_ScaledAdd( system->atoms[i].f, coef.C1dbopi2, bo_ij->dln_BOp_pi2 ); - /*1st, dBO_pi2*/ - rvec_ScaledAdd( system->atoms[i].f, coef.C2dbopi2, bo_ij->dBOp ); - /*2nd, dBO_pi2*/ - rvec_ScaledAdd(system->atoms[i].f, coef.C3dbopi2, workspace->dDeltap_self[i]); - /*3rd, dBO_pi2*/ - - - for( pk = Start_Index(j, bonds); pk < End_Index(j, bonds); ++pk ) { - nbr_k = &(bonds->select.bond_list[pk]); - k = nbr_k->nbr; - - rvec_ScaledAdd( system->atoms[k].f, -coef.C3dbo, nbr_k->bo_data.dBOp ); - /*3rd, dBO*/ - rvec_ScaledAdd( system->atoms[k].f, -coef.C3dDelta, nbr_k->bo_data.dBOp ); - /*dDelta*/ - rvec_ScaledAdd( system->atoms[k].f, -coef.C4dbopi, nbr_k->bo_data.dBOp ); - /*4th, dBOpi*/ - rvec_ScaledAdd( system->atoms[k].f, -coef.C4dbopi2, nbr_k->bo_data.dBOp ); - /*4th, dBOpi2*/ - } - - rvec_ScaledAdd( system->atoms[j].f, -coef.C1dbo, bo_ij->dBOp ); - /*1st, dBO*/ - rvec_ScaledAdd( system->atoms[j].f, coef.C3dbo, workspace->dDeltap_self[j] ); - /*2nd, dBO*/ - - rvec_ScaledAdd( system->atoms[j].f, -coef.C1dDelta, bo_ij->dBOp ); - /*1st, dBO*/ - rvec_ScaledAdd(system->atoms[j].f, coef.C3dDelta, workspace->dDeltap_self[j]); - /*2nd, dBO*/ - - rvec_ScaledAdd( system->atoms[j].f, -coef.C1dbopi, bo_ij->dln_BOp_pi ); - /*1st, dBOpi*/ - rvec_ScaledAdd( system->atoms[j].f, -coef.C2dbopi, bo_ij->dBOp ); - /*2nd, dBOpi*/ - rvec_ScaledAdd(system->atoms[j].f, coef.C4dbopi, workspace->dDeltap_self[j]); - /*3rd, dBOpi*/ - - rvec_ScaledAdd( system->atoms[j].f, -coef.C1dbopi2, bo_ij->dln_BOp_pi2 ); - /*1st, dBOpi2*/ - rvec_ScaledAdd( system->atoms[j].f, -coef.C2dbopi2, bo_ij->dBOp ); - /*2nd, dBOpi2*/ - rvec_ScaledAdd(system->atoms[j].f, coef.C4dbopi2, workspace->dDeltap_self[j]); - /*3rd, dBOpi2*/ } @@ -636,436 +649,455 @@ void Add_dBond_to_Forces( int i, int pj, reax_system *system, And this is the case given our method of neighbor generation*/ int Locate_Symmetric_Bond( list *bonds, int i, int j ) { - int start = Start_Index(i, bonds); - int end = End_Index(i, bonds); - int mid = (start + end) / 2; - int mid_nbr; - - while( (mid_nbr = bonds->select.bond_list[mid].nbr) != j ) { - /*fprintf( stderr, "\tstart: %d end: %d mid: %d\n", - start, end, mid );*/ - if( mid_nbr < j ) - start = mid+1; - else end = mid - 1; - - mid = (start + end) / 2; + int start = Start_Index(i, bonds); + int end = End_Index(i, bonds); + int mid = (start + end) / 2; + int mid_nbr; + + while ( (mid_nbr = bonds->select.bond_list[mid].nbr) != j ) + { + /*fprintf( stderr, "\tstart: %d end: %d mid: %d\n", + start, end, mid );*/ + if ( mid_nbr < j ) + start = mid + 1; + else end = mid - 1; + + mid = (start + end) / 2; } - - return mid; + + return mid; } inline void Copy_Neighbor_Data( bond_data *dest, near_neighbor_data *src ) { - dest->nbr = src->nbr; - dest->d = src->d; - rvec_Copy( dest->dvec, src->dvec ); - ivec_Copy( dest->rel_box, src->rel_box ); - /* rvec_Copy( dest->ext_factor, src->ext_factor );*/ + dest->nbr = src->nbr; + dest->d = src->d; + rvec_Copy( dest->dvec, src->dvec ); + ivec_Copy( dest->rel_box, src->rel_box ); + /* rvec_Copy( dest->ext_factor, src->ext_factor );*/ } inline void Copy_Bond_Order_Data( bond_order_data *dest, bond_order_data *src ) { - dest->BO = src->BO; - dest->BO_s = src->BO_s; - dest->BO_pi = src->BO_pi; - dest->BO_pi2 = src->BO_pi2; - - rvec_Scale( dest->dBOp, -1.0, src->dBOp ); - rvec_Scale( dest->dln_BOp_s, -1.0, src->dln_BOp_s ); - rvec_Scale( dest->dln_BOp_pi, -1.0, src->dln_BOp_pi ); - rvec_Scale( dest->dln_BOp_pi2, -1.0, src->dln_BOp_pi2 ); + dest->BO = src->BO; + dest->BO_s = src->BO_s; + dest->BO_pi = src->BO_pi; + dest->BO_pi2 = src->BO_pi2; + + rvec_Scale( dest->dBOp, -1.0, src->dBOp ); + rvec_Scale( dest->dln_BOp_s, -1.0, src->dln_BOp_s ); + rvec_Scale( dest->dln_BOp_pi, -1.0, src->dln_BOp_pi ); + rvec_Scale( dest->dln_BOp_pi2, -1.0, src->dln_BOp_pi2 ); } int compare_bonds( const void *p1, const void *p2 ) { - return ((bond_data *)p1)->nbr - ((bond_data *)p2)->nbr; + return ((bond_data *)p1)->nbr - ((bond_data *)p2)->nbr; } /* A very important and crucial assumption here is that each segment belonging to a different atom in nbrhoods->nbr_list is sorted in its own. This can either be done in the general coordinator function or here */ -void Calculate_Bond_Orders( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Calculate_Bond_Orders( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i, j, pj, type_i, type_j; - int start_i, end_i; - int num_bonds, sym_index; - real p_boc1, p_boc2; - real val_i, Deltap_i, Deltap_boc_i; - real val_j, Deltap_j, Deltap_boc_j; - real temp, f1, f2, f3, f4, f5, f4f5, exp_f4, exp_f5; - real exp_p1i, exp_p2i, exp_p1j, exp_p2j; - real u1_ij, u1_ji, Cf1A_ij, Cf1B_ij, Cf1_ij, Cf1_ji; - real Cf45_ij, Cf45_ji, p_lp1; - real A0_ij, A1_ij, A2_ij, A2_ji, A3_ij, A3_ji; - real explp1; - two_body_parameters *twbp; - bond_order_data *bo_ij, *bo_ji; - single_body_parameters *sbp_i, *sbp_j; - list *bonds = (*lists) + BONDS; + int i, j, pj, type_i, type_j; + int start_i, end_i; + int num_bonds, sym_index; + real p_boc1, p_boc2; + real val_i, Deltap_i, Deltap_boc_i; + real val_j, Deltap_j, Deltap_boc_j; + real temp, f1, f2, f3, f4, f5, f4f5, exp_f4, exp_f5; + real exp_p1i, exp_p2i, exp_p1j, exp_p2j; + real u1_ij, u1_ji, Cf1A_ij, Cf1B_ij, Cf1_ij, Cf1_ji; + real Cf45_ij, Cf45_ji, p_lp1; + real A0_ij, A1_ij, A2_ij, A2_ji, A3_ij, A3_ji; + real explp1; + two_body_parameters *twbp; + bond_order_data *bo_ij, *bo_ji; + single_body_parameters *sbp_i, *sbp_j; + list *bonds = (*lists) + BONDS; #if defined(TEST_FORCES) - int k, pk, start_j, end_j; - int top_dbo=0, top_dDelta=0; - dbond_data *pdbo; - dDelta_data *ptop_dDelta; - list *dDeltas = (*lists) + DDELTA; - list *dBOs = (*lists) + DBO; + int k, pk, start_j, end_j; + int top_dbo = 0, top_dDelta = 0; + dbond_data *pdbo; + dDelta_data *ptop_dDelta; + list *dDeltas = (*lists) + DDELTA; + list *dBOs = (*lists) + DBO; #endif - num_bonds = 0; - p_boc1 = system->reaxprm.gp.l[0]; - p_boc2 = system->reaxprm.gp.l[1]; - - /* Calculate Deltaprime, Deltaprime_boc values */ - for( i = 0; i < system->N; ++i ) { - type_i = system->atoms[i].type; - sbp_i = &(system->reaxprm.sbp[type_i]); - workspace->Deltap[i] = workspace->total_bond_order[i] - sbp_i->valency; - workspace->Deltap_boc[i] = - workspace->total_bond_order[i] - sbp_i->valency_val; - workspace->total_bond_order[i] = 0; - } - // fprintf( stderr, "done with uncorrected bond orders\n" ); - - - /* Corrected Bond Order calculations */ - for( i = 0; i < system->N; ++i ) { - type_i = system->atoms[i].type; - sbp_i = &(system->reaxprm.sbp[type_i]); - val_i = sbp_i->valency; - Deltap_i = workspace->Deltap[i]; - Deltap_boc_i = workspace->Deltap_boc[i]; - start_i = Start_Index(i, bonds); - end_i = End_Index(i, bonds); - //fprintf( stderr, "i:%d Dp:%g Dbocp:%g s:%d e:%d\n", - // i+1, Deltap_i, Deltap_boc_i, start_i, end_i ); - - for( pj = start_i; pj < end_i; ++pj ) { - j = bonds->select.bond_list[pj].nbr; - type_j = system->atoms[j].type; - bo_ij = &( bonds->select.bond_list[pj].bo_data ); - //fprintf( stderr, "\tj:%d - ubo: %8.3f\n", j+1, bo_ij->BO ); - - if( i < j ) { - twbp = &( system->reaxprm.tbp[type_i][type_j] ); + num_bonds = 0; + p_boc1 = system->reaxprm.gp.l[0]; + p_boc2 = system->reaxprm.gp.l[1]; + + /* Calculate Deltaprime, Deltaprime_boc values */ + for ( i = 0; i < system->N; ++i ) + { + type_i = system->atoms[i].type; + sbp_i = &(system->reaxprm.sbp[type_i]); + workspace->Deltap[i] = workspace->total_bond_order[i] - sbp_i->valency; + workspace->Deltap_boc[i] = + workspace->total_bond_order[i] - sbp_i->valency_val; + workspace->total_bond_order[i] = 0; + } + // fprintf( stderr, "done with uncorrected bond orders\n" ); + + + /* Corrected Bond Order calculations */ + for ( i = 0; i < system->N; ++i ) + { + type_i = system->atoms[i].type; + sbp_i = &(system->reaxprm.sbp[type_i]); + val_i = sbp_i->valency; + Deltap_i = workspace->Deltap[i]; + Deltap_boc_i = workspace->Deltap_boc[i]; + start_i = Start_Index(i, bonds); + end_i = End_Index(i, bonds); + //fprintf( stderr, "i:%d Dp:%g Dbocp:%g s:%d e:%d\n", + // i+1, Deltap_i, Deltap_boc_i, start_i, end_i ); + + for ( pj = start_i; pj < end_i; ++pj ) + { + j = bonds->select.bond_list[pj].nbr; + type_j = system->atoms[j].type; + bo_ij = &( bonds->select.bond_list[pj].bo_data ); + //fprintf( stderr, "\tj:%d - ubo: %8.3f\n", j+1, bo_ij->BO ); + + if ( i < j ) + { + twbp = &( system->reaxprm.tbp[type_i][type_j] ); #ifdef TEST_FORCES - Set_Start_Index( pj, top_dbo, dBOs ); - /* fprintf( stderr, "%6d%6d%23.15e%23.15e%23.15e\n", - workspace->reverse_map[i], workspace->reverse_map[j], - twbp->ovc, twbp->v13cor, bo_ij->BO ); */ + Set_Start_Index( pj, top_dbo, dBOs ); + /* fprintf( stderr, "%6d%6d%23.15e%23.15e%23.15e\n", + workspace->reverse_map[i], workspace->reverse_map[j], + twbp->ovc, twbp->v13cor, bo_ij->BO ); */ #endif - if( twbp->ovc < 0.001 && twbp->v13cor < 0.001 ) { - /* There is no correction to bond orders nor to derivatives of - bond order prime! So we leave bond orders unchanged and - set derivative of bond order coefficients s.t. - dBO = dBOp & dBOxx = dBOxxp in Add_dBO_to_Forces */ - bo_ij->C1dbo = 1.000000; - bo_ij->C2dbo = 0.000000; - bo_ij->C3dbo = 0.000000; - - bo_ij->C1dbopi = bo_ij->BO_pi; - bo_ij->C2dbopi = 0.000000; - bo_ij->C3dbopi = 0.000000; - bo_ij->C4dbopi = 0.000000; - - bo_ij->C1dbopi2 = bo_ij->BO_pi2; - bo_ij->C2dbopi2 = 0.000000; - bo_ij->C3dbopi2 = 0.000000; - bo_ij->C4dbopi2 = 0.000000; - + if ( twbp->ovc < 0.001 && twbp->v13cor < 0.001 ) + { + /* There is no correction to bond orders nor to derivatives of + bond order prime! So we leave bond orders unchanged and + set derivative of bond order coefficients s.t. + dBO = dBOp & dBOxx = dBOxxp in Add_dBO_to_Forces */ + bo_ij->C1dbo = 1.000000; + bo_ij->C2dbo = 0.000000; + bo_ij->C3dbo = 0.000000; + + bo_ij->C1dbopi = bo_ij->BO_pi; + bo_ij->C2dbopi = 0.000000; + bo_ij->C3dbopi = 0.000000; + bo_ij->C4dbopi = 0.000000; + + bo_ij->C1dbopi2 = bo_ij->BO_pi2; + bo_ij->C2dbopi2 = 0.000000; + bo_ij->C3dbopi2 = 0.000000; + bo_ij->C4dbopi2 = 0.000000; + #ifdef TEST_FORCES - pdbo = &(dBOs->select.dbo_list[ top_dbo ]); - - // compute dBO_ij/dr_i - pdbo->wrt = i; - rvec_Copy( pdbo->dBO, bo_ij->dBOp ); - rvec_Scale( pdbo->dBOpi, bo_ij->BO_pi, bo_ij->dln_BOp_pi ); - rvec_Scale( pdbo->dBOpi2, bo_ij->BO_pi2, bo_ij->dln_BOp_pi2 ); - - // compute dBO_ij/dr_j - pdbo++; - pdbo->wrt = j; - rvec_Scale( pdbo->dBO,-1.0,bo_ij->dBOp ); - rvec_Scale( pdbo->dBOpi,-bo_ij->BO_pi,bo_ij->dln_BOp_pi ); - rvec_Scale( pdbo->dBOpi2,-bo_ij->BO_pi2,bo_ij->dln_BOp_pi2 ); - - top_dbo += 2; + pdbo = &(dBOs->select.dbo_list[ top_dbo ]); + + // compute dBO_ij/dr_i + pdbo->wrt = i; + rvec_Copy( pdbo->dBO, bo_ij->dBOp ); + rvec_Scale( pdbo->dBOpi, bo_ij->BO_pi, bo_ij->dln_BOp_pi ); + rvec_Scale( pdbo->dBOpi2, bo_ij->BO_pi2, bo_ij->dln_BOp_pi2 ); + + // compute dBO_ij/dr_j + pdbo++; + pdbo->wrt = j; + rvec_Scale( pdbo->dBO, -1.0, bo_ij->dBOp ); + rvec_Scale( pdbo->dBOpi, -bo_ij->BO_pi, bo_ij->dln_BOp_pi ); + rvec_Scale( pdbo->dBOpi2, -bo_ij->BO_pi2, bo_ij->dln_BOp_pi2 ); + + top_dbo += 2; #endif - } - else { - val_j = system->reaxprm.sbp[type_j].valency; - Deltap_j = workspace->Deltap[j]; - Deltap_boc_j = workspace->Deltap_boc[j]; - - /* on page 1 */ - if( twbp->ovc >= 0.001 ) { - /* Correction for overcoordination */ - exp_p1i = EXP( -p_boc1 * Deltap_i ); - exp_p2i = EXP( -p_boc2 * Deltap_i ); - exp_p1j = EXP( -p_boc1 * Deltap_j ); - exp_p2j = EXP( -p_boc2 * Deltap_j ); - - f2 = exp_p1i + exp_p1j; - f3 = -1.0 / p_boc2 * log( 0.5 * ( exp_p2i + exp_p2j ) ); - f1 = 0.5 * ( ( val_i + f2 )/( val_i + f2 + f3 ) + - ( val_j + f2 )/( val_j + f2 + f3 ) ); - - /*fprintf( stderr,"%6d%6d\t%g %g j:%g %g p_boc:%g %g\n", - i+1, j+1, val_i, Deltap_i, val_j, Deltap_j, p_boc1, p_boc2 ); - fprintf( stderr,"\tf:%g %g %g, exp:%g %g %g %g\n", - f1, f2, f3, exp_p1i, exp_p2i, exp_p1j, exp_p2j );*/ - - /* Now come the derivates */ - /* Bond Order pages 5-7, derivative of f1 */ - temp = f2 + f3; - u1_ij = val_i + temp; - u1_ji = val_j + temp; - Cf1A_ij = 0.5 * f3 * (1.0 / SQR( u1_ij ) + 1.0 / SQR( u1_ji )); - Cf1B_ij = -0.5 * (( u1_ij - f3 ) / SQR( u1_ij ) + - ( u1_ji - f3 ) / SQR( u1_ji )); - - //Cf1_ij = -Cf1A_ij * p_boc1 * exp_p1i + - // Cf1B_ij * exp_p2i / ( exp_p2i + exp_p2j ); - Cf1_ij = 0.50 * ( -p_boc1 * exp_p1i / u1_ij - - ((val_i+f2) / SQR(u1_ij)) * - ( -p_boc1 * exp_p1i + - exp_p2i / ( exp_p2i + exp_p2j ) ) + - -p_boc1 * exp_p1i / u1_ji - - ((val_j+f2)/SQR(u1_ji)) * ( -p_boc1*exp_p1i + - exp_p2i / ( exp_p2i + exp_p2j ) )); - - Cf1_ji = -Cf1A_ij * p_boc1 * exp_p1j + - Cf1B_ij * exp_p2j / ( exp_p2i + exp_p2j ); - //fprintf( stderr, "\tCf1:%g %g\n", Cf1_ij, Cf1_ji ); - } - else { - /* No overcoordination correction! */ - f1 = 1.0; - Cf1_ij = Cf1_ji = 0.0; - } - - if( twbp->v13cor >= 0.001 ) { - /* Correction for 1-3 bond orders */ - exp_f4 =EXP(-(twbp->p_boc4 * SQR( bo_ij->BO ) - - Deltap_boc_i) * twbp->p_boc3 + twbp->p_boc5); - exp_f5 =EXP(-(twbp->p_boc4 * SQR( bo_ij->BO ) - - Deltap_boc_j) * twbp->p_boc3 + twbp->p_boc5); - - f4 = 1. / (1. + exp_f4); - f5 = 1. / (1. + exp_f5); - f4f5 = f4 * f5; - - /* Bond Order pages 8-9, derivative of f4 and f5 */ - /*temp = twbp->p_boc5 - - twbp->p_boc3 * twbp->p_boc4 * SQR( bo_ij->BO ); - u_ij = temp + twbp->p_boc3 * Deltap_boc_i; - u_ji = temp + twbp->p_boc3 * Deltap_boc_j; - Cf45_ij = Cf45( u_ij, u_ji ) / f4f5; - Cf45_ji = Cf45( u_ji, u_ij ) / f4f5;*/ - Cf45_ij = -f4 * exp_f4; - Cf45_ji = -f5 * exp_f5; - } - else { - f4 = f5 = f4f5 = 1.0; - Cf45_ij = Cf45_ji = 0.0; - } - - /* Bond Order page 10, derivative of total bond order */ - A0_ij = f1 * f4f5; - A1_ij = -2 * twbp->p_boc3 * twbp->p_boc4 * bo_ij->BO * - (Cf45_ij + Cf45_ji); - A2_ij = Cf1_ij / f1 + twbp->p_boc3 * Cf45_ij; - A2_ji = Cf1_ji / f1 + twbp->p_boc3 * Cf45_ji; - A3_ij = A2_ij + Cf1_ij / f1; - A3_ji = A2_ji + Cf1_ji / f1; - - /*fprintf( stderr, "\tBO: %f, A0: %f, A1: %f, A2_ij: %f - A2_ji: %f, A3_ij: %f, A3_ji: %f\n", - bo_ij->BO, A0_ij, A1_ij, A2_ij, A2_ji, A3_ij, A3_ji );*/ - - - /* find corrected bond order values and their deriv coefs */ - bo_ij->BO = bo_ij->BO * A0_ij; - bo_ij->BO_pi = bo_ij->BO_pi * A0_ij *f1; - bo_ij->BO_pi2= bo_ij->BO_pi2* A0_ij *f1; - bo_ij->BO_s = bo_ij->BO - ( bo_ij->BO_pi + bo_ij->BO_pi2 ); - - bo_ij->C1dbo = A0_ij + bo_ij->BO * A1_ij; - bo_ij->C2dbo = bo_ij->BO * A2_ij; - bo_ij->C3dbo = bo_ij->BO * A2_ji; - - bo_ij->C1dbopi = f1*f1*f4*f5; - bo_ij->C2dbopi = bo_ij->BO_pi * A1_ij; - bo_ij->C3dbopi = bo_ij->BO_pi * A3_ij; - bo_ij->C4dbopi = bo_ij->BO_pi * A3_ji; - - bo_ij->C1dbopi2 = f1*f1*f4*f5; - bo_ij->C2dbopi2 = bo_ij->BO_pi2 * A1_ij; - bo_ij->C3dbopi2 = bo_ij->BO_pi2 * A3_ij; - bo_ij->C4dbopi2 = bo_ij->BO_pi2 * A3_ji; - + } + else + { + val_j = system->reaxprm.sbp[type_j].valency; + Deltap_j = workspace->Deltap[j]; + Deltap_boc_j = workspace->Deltap_boc[j]; + + /* on page 1 */ + if ( twbp->ovc >= 0.001 ) + { + /* Correction for overcoordination */ + exp_p1i = EXP( -p_boc1 * Deltap_i ); + exp_p2i = EXP( -p_boc2 * Deltap_i ); + exp_p1j = EXP( -p_boc1 * Deltap_j ); + exp_p2j = EXP( -p_boc2 * Deltap_j ); + + f2 = exp_p1i + exp_p1j; + f3 = -1.0 / p_boc2 * log( 0.5 * ( exp_p2i + exp_p2j ) ); + f1 = 0.5 * ( ( val_i + f2 ) / ( val_i + f2 + f3 ) + + ( val_j + f2 ) / ( val_j + f2 + f3 ) ); + + /*fprintf( stderr,"%6d%6d\t%g %g j:%g %g p_boc:%g %g\n", + i+1, j+1, val_i, Deltap_i, val_j, Deltap_j, p_boc1, p_boc2 ); + fprintf( stderr,"\tf:%g %g %g, exp:%g %g %g %g\n", + f1, f2, f3, exp_p1i, exp_p2i, exp_p1j, exp_p2j );*/ + + /* Now come the derivates */ + /* Bond Order pages 5-7, derivative of f1 */ + temp = f2 + f3; + u1_ij = val_i + temp; + u1_ji = val_j + temp; + Cf1A_ij = 0.5 * f3 * (1.0 / SQR( u1_ij ) + 1.0 / SQR( u1_ji )); + Cf1B_ij = -0.5 * (( u1_ij - f3 ) / SQR( u1_ij ) + + ( u1_ji - f3 ) / SQR( u1_ji )); + + //Cf1_ij = -Cf1A_ij * p_boc1 * exp_p1i + + // Cf1B_ij * exp_p2i / ( exp_p2i + exp_p2j ); + Cf1_ij = 0.50 * ( -p_boc1 * exp_p1i / u1_ij - + ((val_i + f2) / SQR(u1_ij)) * + ( -p_boc1 * exp_p1i + + exp_p2i / ( exp_p2i + exp_p2j ) ) + + -p_boc1 * exp_p1i / u1_ji - + ((val_j + f2) / SQR(u1_ji)) * ( -p_boc1 * exp_p1i + + exp_p2i / ( exp_p2i + exp_p2j ) )); + + Cf1_ji = -Cf1A_ij * p_boc1 * exp_p1j + + Cf1B_ij * exp_p2j / ( exp_p2i + exp_p2j ); + //fprintf( stderr, "\tCf1:%g %g\n", Cf1_ij, Cf1_ji ); + } + else + { + /* No overcoordination correction! */ + f1 = 1.0; + Cf1_ij = Cf1_ji = 0.0; + } + + if ( twbp->v13cor >= 0.001 ) + { + /* Correction for 1-3 bond orders */ + exp_f4 = EXP(-(twbp->p_boc4 * SQR( bo_ij->BO ) - + Deltap_boc_i) * twbp->p_boc3 + twbp->p_boc5); + exp_f5 = EXP(-(twbp->p_boc4 * SQR( bo_ij->BO ) - + Deltap_boc_j) * twbp->p_boc3 + twbp->p_boc5); + + f4 = 1. / (1. + exp_f4); + f5 = 1. / (1. + exp_f5); + f4f5 = f4 * f5; + + /* Bond Order pages 8-9, derivative of f4 and f5 */ + /*temp = twbp->p_boc5 - + twbp->p_boc3 * twbp->p_boc4 * SQR( bo_ij->BO ); + u_ij = temp + twbp->p_boc3 * Deltap_boc_i; + u_ji = temp + twbp->p_boc3 * Deltap_boc_j; + Cf45_ij = Cf45( u_ij, u_ji ) / f4f5; + Cf45_ji = Cf45( u_ji, u_ij ) / f4f5;*/ + Cf45_ij = -f4 * exp_f4; + Cf45_ji = -f5 * exp_f5; + } + else + { + f4 = f5 = f4f5 = 1.0; + Cf45_ij = Cf45_ji = 0.0; + } + + /* Bond Order page 10, derivative of total bond order */ + A0_ij = f1 * f4f5; + A1_ij = -2 * twbp->p_boc3 * twbp->p_boc4 * bo_ij->BO * + (Cf45_ij + Cf45_ji); + A2_ij = Cf1_ij / f1 + twbp->p_boc3 * Cf45_ij; + A2_ji = Cf1_ji / f1 + twbp->p_boc3 * Cf45_ji; + A3_ij = A2_ij + Cf1_ij / f1; + A3_ji = A2_ji + Cf1_ji / f1; + + /*fprintf( stderr, "\tBO: %f, A0: %f, A1: %f, A2_ij: %f + A2_ji: %f, A3_ij: %f, A3_ji: %f\n", + bo_ij->BO, A0_ij, A1_ij, A2_ij, A2_ji, A3_ij, A3_ji );*/ + + + /* find corrected bond order values and their deriv coefs */ + bo_ij->BO = bo_ij->BO * A0_ij; + bo_ij->BO_pi = bo_ij->BO_pi * A0_ij * f1; + bo_ij->BO_pi2 = bo_ij->BO_pi2 * A0_ij * f1; + bo_ij->BO_s = bo_ij->BO - ( bo_ij->BO_pi + bo_ij->BO_pi2 ); + + bo_ij->C1dbo = A0_ij + bo_ij->BO * A1_ij; + bo_ij->C2dbo = bo_ij->BO * A2_ij; + bo_ij->C3dbo = bo_ij->BO * A2_ji; + + bo_ij->C1dbopi = f1 * f1 * f4 * f5; + bo_ij->C2dbopi = bo_ij->BO_pi * A1_ij; + bo_ij->C3dbopi = bo_ij->BO_pi * A3_ij; + bo_ij->C4dbopi = bo_ij->BO_pi * A3_ji; + + bo_ij->C1dbopi2 = f1 * f1 * f4 * f5; + bo_ij->C2dbopi2 = bo_ij->BO_pi2 * A1_ij; + bo_ij->C3dbopi2 = bo_ij->BO_pi2 * A3_ij; + bo_ij->C4dbopi2 = bo_ij->BO_pi2 * A3_ji; + #ifdef TEST_FORCES - /*fprintf( stderr, "%6d%6d%13.6f%13.6f%13.6f%13.6f\n", - i+1, j+1, bo_ij->BO, bo_ij->C1dbo, Cf45_ij, Cf45_ji );*/ - - /* fprintf( stderr, "%6d%6d%13.6f%13.6f%13.6f%13.6f\n", - //"%6d%6d%10.6f%10.6f%10.6f%10.6f\n%10.6f%10.6f%10.6f\n%10.6f%10.6f%10.6f%10.6f\n%10.6f%10.6f%10.6f%10.6f\n\n", - workspace->orig_id[i], workspace->orig_id[j] - A0_ij, A1_ij, A2_ij, A2_ji, A3_ij, A3_ji - bo_ij->BO, bo_ij->BO_pi, bo_ij->BO_pi2, bo_ij->BO_s, - bo_ij->C1dbo, bo_ij->C2dbo, bo_ij->C3dbo, - bo_ij->C1dbopi,bo_ij->C2dbopi,bo_ij->C3dbopi,bo_ij->C4dbopi, - bo_ij->C1dbopi2,bo_ij->C2dbopi2,bo_ij->C3dbopi2,bo_ij->C4dbopi2 - ); */ - - Calculate_dBO( i, pj, workspace, lists, &top_dbo ); + /*fprintf( stderr, "%6d%6d%13.6f%13.6f%13.6f%13.6f\n", + i+1, j+1, bo_ij->BO, bo_ij->C1dbo, Cf45_ij, Cf45_ji );*/ + + /* fprintf( stderr, "%6d%6d%13.6f%13.6f%13.6f%13.6f\n", + //"%6d%6d%10.6f%10.6f%10.6f%10.6f\n%10.6f%10.6f%10.6f\n%10.6f%10.6f%10.6f%10.6f\n%10.6f%10.6f%10.6f%10.6f\n\n", + workspace->orig_id[i], workspace->orig_id[j] + A0_ij, A1_ij, A2_ij, A2_ji, A3_ij, A3_ji + bo_ij->BO, bo_ij->BO_pi, bo_ij->BO_pi2, bo_ij->BO_s, + bo_ij->C1dbo, bo_ij->C2dbo, bo_ij->C3dbo, + bo_ij->C1dbopi,bo_ij->C2dbopi,bo_ij->C3dbopi,bo_ij->C4dbopi, + bo_ij->C1dbopi2,bo_ij->C2dbopi2,bo_ij->C3dbopi2,bo_ij->C4dbopi2 + ); */ + + Calculate_dBO( i, pj, workspace, lists, &top_dbo ); #endif - } - - /* neglect bonds that are < 1e-10 */ - if( bo_ij->BO < 1e-10 ) - bo_ij->BO = 0.0; - if( bo_ij->BO_s < 1e-10 ) - bo_ij->BO_s = 0.0; - if( bo_ij->BO_pi < 1e-10 ) - bo_ij->BO_pi = 0.0; - if( bo_ij->BO_pi2 < 1e-10 ) - bo_ij->BO_pi2 = 0.0; - - workspace->total_bond_order[i] += bo_ij->BO; // now keeps total_BO - - - /* fprintf( stderr, "%d %d\t%g %g %g %g\n - Cdbo:\t%g %g %g\n - Cdbopi:\t%g %g %g %g\n - Cdbopi2:%g %g %g %g\n\n", - i+1, j+1, bonds->select.bond_list[ pj ].d, - bo_ij->BO,bo_ij->BO_pi, bo_ij->BO_pi2, - bo_ij->C1dbo, bo_ij->C2dbo, bo_ij->C3dbo, - bo_ij->C1dbopi, bo_ij->C2dbopi, bo_ij->C3dbopi, bo_ij->C4dbopi, - bo_ij->C1dbopi2, bo_ij->C2dbopi2, - bo_ij->C3dbopi2, bo_ij->C4dbopi2 ); */ - - /* fprintf( stderr, "%d %d, BO:%f BO_s:%f BO_pi:%f BO_pi2:%f\n", - i+1,j+1,bo_ij->BO,bo_ij->BO_s,bo_ij->BO_pi,bo_ij->BO_pi2 ); */ - + } + + /* neglect bonds that are < 1e-10 */ + if ( bo_ij->BO < 1e-10 ) + bo_ij->BO = 0.0; + if ( bo_ij->BO_s < 1e-10 ) + bo_ij->BO_s = 0.0; + if ( bo_ij->BO_pi < 1e-10 ) + bo_ij->BO_pi = 0.0; + if ( bo_ij->BO_pi2 < 1e-10 ) + bo_ij->BO_pi2 = 0.0; + + workspace->total_bond_order[i] += bo_ij->BO; // now keeps total_BO + + + /* fprintf( stderr, "%d %d\t%g %g %g %g\n + Cdbo:\t%g %g %g\n + Cdbopi:\t%g %g %g %g\n + Cdbopi2:%g %g %g %g\n\n", + i+1, j+1, bonds->select.bond_list[ pj ].d, + bo_ij->BO,bo_ij->BO_pi, bo_ij->BO_pi2, + bo_ij->C1dbo, bo_ij->C2dbo, bo_ij->C3dbo, + bo_ij->C1dbopi, bo_ij->C2dbopi, bo_ij->C3dbopi, bo_ij->C4dbopi, + bo_ij->C1dbopi2, bo_ij->C2dbopi2, + bo_ij->C3dbopi2, bo_ij->C4dbopi2 ); */ + + /* fprintf( stderr, "%d %d, BO:%f BO_s:%f BO_pi:%f BO_pi2:%f\n", + i+1,j+1,bo_ij->BO,bo_ij->BO_s,bo_ij->BO_pi,bo_ij->BO_pi2 ); */ + #ifdef TEST_FORCES - Set_End_Index( pj, top_dbo, dBOs ); - Add_dBO( system, lists, i, pj, 1.0, workspace->dDelta ); + Set_End_Index( pj, top_dbo, dBOs ); + Add_dBO( system, lists, i, pj, 1.0, workspace->dDelta ); #endif - } - else { - /* We only need to update bond orders from bo_ji - everything else is set in uncorrected_bo calculations */ - sym_index = bonds->select.bond_list[pj].sym_index; - bo_ji = &(bonds->select.bond_list[ sym_index ].bo_data); - bo_ij->BO = bo_ji->BO; - bo_ij->BO_s = bo_ji->BO_s; - bo_ij->BO_pi = bo_ji->BO_pi; - bo_ij->BO_pi2 = bo_ji->BO_pi2; - - workspace->total_bond_order[i] += bo_ij->BO; // now keeps total_BO + } + else + { + /* We only need to update bond orders from bo_ji + everything else is set in uncorrected_bo calculations */ + sym_index = bonds->select.bond_list[pj].sym_index; + bo_ji = &(bonds->select.bond_list[ sym_index ].bo_data); + bo_ij->BO = bo_ji->BO; + bo_ij->BO_s = bo_ji->BO_s; + bo_ij->BO_pi = bo_ji->BO_pi; + bo_ij->BO_pi2 = bo_ji->BO_pi2; + + workspace->total_bond_order[i] += bo_ij->BO; // now keeps total_BO #ifdef TEST_FORCES - Add_dBO( system, lists, j, sym_index, 1.0, workspace->dDelta ); + Add_dBO( system, lists, j, sym_index, 1.0, workspace->dDelta ); #endif - } - } - -#ifdef TEST_FORCES - // fprintf( stderr, "dDelta computations\nj:" ); - Set_Start_Index( i, top_dDelta, dDeltas ); - ptop_dDelta = &( dDeltas->select.dDelta_list[top_dDelta] ); - - for( pj = start_i; pj < end_i; ++pj ) { - j = bonds->select.bond_list[pj].nbr; - // fprintf( stderr, "%d ", j ); - - if( !rvec_isZero( workspace->dDelta[j] ) ) { - ptop_dDelta->wrt = j; - rvec_Copy( ptop_dDelta->dVal, workspace->dDelta[j] ); - rvec_MakeZero( workspace->dDelta[j] ); - ++top_dDelta, ++ptop_dDelta; - } - - start_j = Start_Index(j, bonds); - end_j = End_Index(j, bonds); - for( pk = start_j; pk < end_j; ++pk ) { - k = bonds->select.bond_list[pk].nbr; - if( !rvec_isZero( workspace->dDelta[k] ) ) { - ptop_dDelta->wrt = k; - rvec_Copy( ptop_dDelta->dVal, workspace->dDelta[k] ); - rvec_MakeZero( workspace->dDelta[k] ); - ++top_dDelta, ++ptop_dDelta; - } - } - } - - Set_End_Index( i, top_dDelta, dDeltas ); - - /*for( pj=Start_Index(i,dDeltas); pj<End_Index(i,dDeltas); ++pj ) - fprintf( stdout, "dDel: %d %d [%g %g %g]\n", - i+1, dDeltas->select.dDelta_list[pj].wrt+1, - dDeltas->select.dDelta_list[pj].dVal[0], - dDeltas->select.dDelta_list[pj].dVal[1], - dDeltas->select.dDelta_list[pj].dVal[2] );*/ + } + } + +#ifdef TEST_FORCES + // fprintf( stderr, "dDelta computations\nj:" ); + Set_Start_Index( i, top_dDelta, dDeltas ); + ptop_dDelta = &( dDeltas->select.dDelta_list[top_dDelta] ); + + for ( pj = start_i; pj < end_i; ++pj ) + { + j = bonds->select.bond_list[pj].nbr; + // fprintf( stderr, "%d ", j ); + + if ( !rvec_isZero( workspace->dDelta[j] ) ) + { + ptop_dDelta->wrt = j; + rvec_Copy( ptop_dDelta->dVal, workspace->dDelta[j] ); + rvec_MakeZero( workspace->dDelta[j] ); + ++top_dDelta, ++ptop_dDelta; + } + + start_j = Start_Index(j, bonds); + end_j = End_Index(j, bonds); + for ( pk = start_j; pk < end_j; ++pk ) + { + k = bonds->select.bond_list[pk].nbr; + if ( !rvec_isZero( workspace->dDelta[k] ) ) + { + ptop_dDelta->wrt = k; + rvec_Copy( ptop_dDelta->dVal, workspace->dDelta[k] ); + rvec_MakeZero( workspace->dDelta[k] ); + ++top_dDelta, ++ptop_dDelta; + } + } + } + + Set_End_Index( i, top_dDelta, dDeltas ); + + /*for( pj=Start_Index(i,dDeltas); pj<End_Index(i,dDeltas); ++pj ) + fprintf( stdout, "dDel: %d %d [%g %g %g]\n", + i+1, dDeltas->select.dDelta_list[pj].wrt+1, + dDeltas->select.dDelta_list[pj].dVal[0], + dDeltas->select.dDelta_list[pj].dVal[1], + dDeltas->select.dDelta_list[pj].dVal[2] );*/ #endif - } - - /*fprintf(stderr,"\tCalculated actual bond orders ...\n" ); - fprintf(stderr,"%6s%8s%8s%8s%8s%8s%8s%8s\n", - "atom", "Delta", "Delta_e", "Delta_boc", "nlp", - "Delta_lp", "Clp", "dDelta_lp" );*/ - - p_lp1 = system->reaxprm.gp.l[15]; - /* Calculate some helper variables that are used at many places - throughout force calculations */ - for( j = 0; j < system->N; ++j ) { - type_j = system->atoms[j].type; - sbp_j = &(system->reaxprm.sbp[ type_j ]); - - workspace->Delta[j] = workspace->total_bond_order[j] - sbp_j->valency; - workspace->Delta_e[j] = workspace->total_bond_order[j] - sbp_j->valency_e; - workspace->Delta_boc[j] = workspace->total_bond_order[j] - - sbp_j->valency_boc; - - workspace->vlpex[j] = workspace->Delta_e[j] - - 2.0 * (int)(workspace->Delta_e[j]/2.0); - explp1 = EXP(-p_lp1 * SQR(2.0 + workspace->vlpex[j])); - workspace->nlp[j] = explp1 - (int)(workspace->Delta_e[j] / 2.0); - workspace->Delta_lp[j] = sbp_j->nlp_opt - workspace->nlp[j]; - workspace->Clp[j] = 2.0 * p_lp1 * explp1 * (2.0 + workspace->vlpex[j]); - /* Adri uses different dDelta_lp values than the ones in notes... */ - workspace->dDelta_lp[j] = workspace->Clp[j]; - //workspace->dDelta_lp[j] = workspace->Clp[j] + (0.5-workspace->Clp[j]) * - //((fabs(workspace->Delta_e[j]/2.0 - - // (int)(workspace->Delta_e[j]/2.0)) < 0.1) ? 1 : 0 ); - - if( sbp_j->mass > 21.0 ) { - workspace->nlp_temp[j] = 0.5 * (sbp_j->valency_e - sbp_j->valency); - workspace->Delta_lp_temp[j] = sbp_j->nlp_opt - workspace->nlp_temp[j]; - workspace->dDelta_lp_temp[j] = 0.; - } - else { - workspace->nlp_temp[j] = workspace->nlp[j]; - workspace->Delta_lp_temp[j] = sbp_j->nlp_opt - workspace->nlp_temp[j]; - workspace->dDelta_lp_temp[j] = workspace->Clp[j]; } - //fprintf( stderr, "%d\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n", - //j, workspace->Delta[j], workspace->Delta_e[j], workspace->Delta_boc[j], - //workspace->nlp[j], system->reaxprm.sbp[type_j].nlp_opt, - //workspace->Delta_lp[j], workspace->Clp[j], workspace->dDelta_lp[j] ); - } + /*fprintf(stderr,"\tCalculated actual bond orders ...\n" ); + fprintf(stderr,"%6s%8s%8s%8s%8s%8s%8s%8s\n", + "atom", "Delta", "Delta_e", "Delta_boc", "nlp", + "Delta_lp", "Clp", "dDelta_lp" );*/ + + p_lp1 = system->reaxprm.gp.l[15]; + /* Calculate some helper variables that are used at many places + throughout force calculations */ + for ( j = 0; j < system->N; ++j ) + { + type_j = system->atoms[j].type; + sbp_j = &(system->reaxprm.sbp[ type_j ]); + + workspace->Delta[j] = workspace->total_bond_order[j] - sbp_j->valency; + workspace->Delta_e[j] = workspace->total_bond_order[j] - sbp_j->valency_e; + workspace->Delta_boc[j] = workspace->total_bond_order[j] - + sbp_j->valency_boc; + + workspace->vlpex[j] = workspace->Delta_e[j] - + 2.0 * (int)(workspace->Delta_e[j] / 2.0); + explp1 = EXP(-p_lp1 * SQR(2.0 + workspace->vlpex[j])); + workspace->nlp[j] = explp1 - (int)(workspace->Delta_e[j] / 2.0); + workspace->Delta_lp[j] = sbp_j->nlp_opt - workspace->nlp[j]; + workspace->Clp[j] = 2.0 * p_lp1 * explp1 * (2.0 + workspace->vlpex[j]); + /* Adri uses different dDelta_lp values than the ones in notes... */ + workspace->dDelta_lp[j] = workspace->Clp[j]; + //workspace->dDelta_lp[j] = workspace->Clp[j] + (0.5-workspace->Clp[j]) * + //((fabs(workspace->Delta_e[j]/2.0 - + // (int)(workspace->Delta_e[j]/2.0)) < 0.1) ? 1 : 0 ); + + if ( sbp_j->mass > 21.0 ) + { + workspace->nlp_temp[j] = 0.5 * (sbp_j->valency_e - sbp_j->valency); + workspace->Delta_lp_temp[j] = sbp_j->nlp_opt - workspace->nlp_temp[j]; + workspace->dDelta_lp_temp[j] = 0.; + } + else + { + workspace->nlp_temp[j] = workspace->nlp[j]; + workspace->Delta_lp_temp[j] = sbp_j->nlp_opt - workspace->nlp_temp[j]; + workspace->dDelta_lp_temp[j] = workspace->Clp[j]; + } + + //fprintf( stderr, "%d\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n", + //j, workspace->Delta[j], workspace->Delta_e[j], workspace->Delta_boc[j], + //workspace->nlp[j], system->reaxprm.sbp[type_j].nlp_opt, + //workspace->Delta_lp[j], workspace->Clp[j], workspace->dDelta_lp[j] ); + } - //Print_Bonds( system, bonds, "sbonds.out" ); + //Print_Bonds( system, bonds, "sbonds.out" ); #if defined(DEBUG) - fprintf( stderr, "Number of bonds: %d\n", num_bonds ); - Print_Bond_Orders( system, control, data, workspace, lists, out_control ); + fprintf( stderr, "Number of bonds: %d\n", num_bonds ); + Print_Bond_Orders( system, control, data, workspace, lists, out_control ); #endif } diff --git a/puremd_rc_1003/sPuReMD/bond_orders.h b/puremd_rc_1003/sPuReMD/bond_orders.h index 8ac3492c..b6ca199e 100644 --- a/puremd_rc_1003/sPuReMD/bond_orders.h +++ b/puremd_rc_1003/sPuReMD/bond_orders.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -24,12 +24,13 @@ #include "mytypes.h" -typedef struct{ - real C1dbo, C2dbo, C3dbo; - real C1dbopi, C2dbopi, C3dbopi, C4dbopi; - real C1dbopi2, C2dbopi2, C3dbopi2, C4dbopi2; - real C1dDelta, C2dDelta, C3dDelta; -}dbond_coefficients; +typedef struct +{ + real C1dbo, C2dbo, C3dbo; + real C1dbopi, C2dbopi, C3dbopi, C4dbopi; + real C1dbopi2, C2dbopi2, C3dbopi2, C4dbopi2; + real C1dDelta, C2dDelta, C3dDelta; +} dbond_coefficients; #ifdef TEST_FORCES void Get_dBO( reax_system*, list**, int, int, real, rvec* ); @@ -45,10 +46,10 @@ void Add_dDelta( reax_system*, list**, int, real, rvec* ); void Add_dDelta_to_Forces( reax_system *, list**, int, real ); #endif -void Add_dBond_to_Forces( int, int, reax_system*, simulation_data*, - static_storage*, list** ); -void Add_dBond_to_Forces_NPT( int, int, reax_system*, simulation_data*, - static_storage*, list** ); +void Add_dBond_to_Forces( int, int, reax_system*, simulation_data*, + static_storage*, list** ); +void Add_dBond_to_Forces_NPT( int, int, reax_system*, simulation_data*, + static_storage*, list** ); void Calculate_Bond_Orders( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); + static_storage*, list**, output_controls* ); #endif diff --git a/puremd_rc_1003/sPuReMD/box.c b/puremd_rc_1003/sPuReMD/box.c index d0daa6a5..c9bd50c4 100644 --- a/puremd_rc_1003/sPuReMD/box.c +++ b/puremd_rc_1003/sPuReMD/box.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -23,540 +23,565 @@ #include "vector.h" -void Init_Box_From_CRYST(real a, real b, real c, - real alpha, real beta, real gamma, - simulation_box* box ) +void Init_Box_From_CRYST(real a, real b, real c, + real alpha, real beta, real gamma, + simulation_box* box ) { - double c_alpha, c_beta, c_gamma, s_gamma, zi; + double c_alpha, c_beta, c_gamma, s_gamma, zi; - c_alpha = cos(DEG2RAD(alpha)); - c_beta = cos(DEG2RAD(beta)); - c_gamma = cos(DEG2RAD(gamma)); - s_gamma = sin(DEG2RAD(gamma)); + c_alpha = cos(DEG2RAD(alpha)); + c_beta = cos(DEG2RAD(beta)); + c_gamma = cos(DEG2RAD(gamma)); + s_gamma = sin(DEG2RAD(gamma)); - zi = (c_alpha - c_beta * c_gamma)/s_gamma; + zi = (c_alpha - c_beta * c_gamma) / s_gamma; - box->box[0][0] = a; - box->box[0][1] = 0.0; - box->box[0][2] = 0.0; - - box->box[1][0] = b * c_gamma; - box->box[1][1] = b * s_gamma; - box->box[1][2] = 0.0; + box->box[0][0] = a; + box->box[0][1] = 0.0; + box->box[0][2] = 0.0; - box->box[2][0] = c * c_beta; - box->box[2][1] = c * zi; - box->box[2][2] = c * SQRT(1.0 - SQR(c_beta) - SQR(zi)); + box->box[1][0] = b * c_gamma; + box->box[1][1] = b * s_gamma; + box->box[1][2] = 0.0; - Make_Consistent( box ); + box->box[2][0] = c * c_beta; + box->box[2][1] = c * zi; + box->box[2][2] = c * SQRT(1.0 - SQR(c_beta) - SQR(zi)); + + Make_Consistent( box ); #if defined(DEBUG_FOCUS) - fprintf( stderr, "box is %8.2f x %8.2f x %8.2f\n", - box->box[0][0], box->box[1][1], box->box[2][2] ); + fprintf( stderr, "box is %8.2f x %8.2f x %8.2f\n", + box->box[0][0], box->box[1][1], box->box[2][2] ); #endif } void Update_Box( rtensor box_tensor, simulation_box* box ) { - int i, j; + int i, j; - for (i=0; i < 3; i++) - for (j=0; j < 3; j++) - box->box[i][j] = box_tensor[i][j]; + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + box->box[i][j] = box_tensor[i][j]; - Make_Consistent( box ); + Make_Consistent( box ); } void Update_Box_Isotropic( simulation_box *box, real mu ) { - /*box->box[0][0] = - POW( V_new / ( box->side_prop[1] * box->side_prop[2] ), 1.0/3.0 ); - box->box[1][1] = box->box[0][0] * box->side_prop[1]; - box->box[2][2] = box->box[0][0] * box->side_prop[2]; - */ - rtensor_Copy( box->old_box, box->box ); - box->box[0][0] *= mu; - box->box[1][1] *= mu; - box->box[2][2] *= mu; - - box->volume = box->box[0][0]*box->box[1][1]*box->box[2][2]; - Make_Consistent(box/*, periodic*/); + /*box->box[0][0] = + POW( V_new / ( box->side_prop[1] * box->side_prop[2] ), 1.0/3.0 ); + box->box[1][1] = box->box[0][0] * box->side_prop[1]; + box->box[2][2] = box->box[0][0] * box->side_prop[2]; + */ + rtensor_Copy( box->old_box, box->box ); + box->box[0][0] *= mu; + box->box[1][1] *= mu; + box->box[2][2] *= mu; + + box->volume = box->box[0][0] * box->box[1][1] * box->box[2][2]; + Make_Consistent(box/*, periodic*/); } void Update_Box_SemiIsotropic( simulation_box *box, rvec mu ) { - /*box->box[0][0] = - POW( V_new / ( box->side_prop[1] * box->side_prop[2] ), 1.0/3.0 ); - box->box[1][1] = box->box[0][0] * box->side_prop[1]; - box->box[2][2] = box->box[0][0] * box->side_prop[2]; */ - rtensor_Copy( box->old_box, box->box ); - box->box[0][0] *= mu[0]; - box->box[1][1] *= mu[1]; - box->box[2][2] *= mu[2]; - - box->volume = box->box[0][0]*box->box[1][1]*box->box[2][2]; - Make_Consistent(box); + /*box->box[0][0] = + POW( V_new / ( box->side_prop[1] * box->side_prop[2] ), 1.0/3.0 ); + box->box[1][1] = box->box[0][0] * box->side_prop[1]; + box->box[2][2] = box->box[0][0] * box->side_prop[2]; */ + rtensor_Copy( box->old_box, box->box ); + box->box[0][0] *= mu[0]; + box->box[1][1] *= mu[1]; + box->box[2][2] *= mu[2]; + + box->volume = box->box[0][0] * box->box[1][1] * box->box[2][2]; + Make_Consistent(box); } void Make_Consistent(simulation_box* box) { - real one_vol; - - box->volume = - box->box[0][0] * (box->box[1][1]*box->box[2][2] - - box->box[2][1]*box->box[2][1]) + - box->box[0][1] * (box->box[2][0]*box->box[1][2] - - box->box[1][0]*box->box[2][2]) + - box->box[0][2] * (box->box[1][0]*box->box[2][1] - - box->box[2][0]*box->box[1][1]); - - one_vol = 1.0/box->volume; - - box->box_inv[0][0] = (box->box[1][1]*box->box[2][2] - - box->box[1][2]*box->box[2][1]) * one_vol; - box->box_inv[0][1] = (box->box[0][2]*box->box[2][1] - - box->box[0][1]*box->box[2][2]) * one_vol; - box->box_inv[0][2] = (box->box[0][1]*box->box[1][2] - - box->box[0][2]*box->box[1][1]) * one_vol; - - box->box_inv[1][0] = (box->box[1][2]*box->box[2][0] - - box->box[1][0]*box->box[2][2]) * one_vol; - box->box_inv[1][1] = (box->box[0][0]*box->box[2][2] - - box->box[0][2]*box->box[2][0]) * one_vol; - box->box_inv[1][2] = (box->box[0][2]*box->box[1][0] - - box->box[0][0]*box->box[1][2]) * one_vol; - - box->box_inv[2][0] = (box->box[1][0]*box->box[2][1] - - box->box[1][1]*box->box[2][0]) * one_vol; - box->box_inv[2][1] = (box->box[0][1]*box->box[2][0] - - box->box[0][0]*box->box[2][1]) * one_vol; - box->box_inv[2][2] = (box->box[0][0]*box->box[1][1] - - box->box[0][1]*box->box[1][0]) * one_vol; - - box->box_norms[0] = SQRT( SQR(box->box[0][0]) + - SQR(box->box[0][1]) + - SQR(box->box[0][2]) ); - box->box_norms[1] = SQRT( SQR(box->box[1][0]) + - SQR(box->box[1][1]) + - SQR(box->box[1][2]) ); - box->box_norms[2] = SQRT( SQR(box->box[2][0]) + - SQR(box->box[2][1]) + - SQR(box->box[2][2]) ); - - box->trans[0][0] = box->box[0][0]/box->box_norms[0]; - box->trans[0][1] = box->box[1][0]/box->box_norms[0]; - box->trans[0][2] = box->box[2][0]/box->box_norms[0]; - - box->trans[1][0] = box->box[0][1]/box->box_norms[1]; - box->trans[1][1] = box->box[1][1]/box->box_norms[1]; - box->trans[1][2] = box->box[2][1]/box->box_norms[1]; - - box->trans[2][0] = box->box[0][2]/box->box_norms[2]; - box->trans[2][1] = box->box[1][2]/box->box_norms[2]; - box->trans[2][2] = box->box[2][2]/box->box_norms[2]; - - one_vol = box->box_norms[0]*box->box_norms[1]*box->box_norms[2]*one_vol; - - box->trans_inv[0][0] = (box->trans[1][1]*box->trans[2][2] - - box->trans[1][2]*box->trans[2][1]) * one_vol; - box->trans_inv[0][1] = (box->trans[0][2]*box->trans[2][1] - - box->trans[0][1]*box->trans[2][2]) * one_vol; - box->trans_inv[0][2] = (box->trans[0][1]*box->trans[1][2] - - box->trans[0][2]*box->trans[1][1]) * one_vol; - - box->trans_inv[1][0] = (box->trans[1][2]*box->trans[2][0] - - box->trans[1][0]*box->trans[2][2]) * one_vol; - box->trans_inv[1][1] = (box->trans[0][0]*box->trans[2][2] - - box->trans[0][2]*box->trans[2][0]) * one_vol; - box->trans_inv[1][2] = (box->trans[0][2]*box->trans[1][0] - - box->trans[0][0]*box->trans[1][2]) * one_vol; - - box->trans_inv[2][0] = (box->trans[1][0]*box->trans[2][1] - - box->trans[1][1]*box->trans[2][0]) * one_vol; - box->trans_inv[2][1] = (box->trans[0][1]*box->trans[2][0] - - box->trans[0][0]*box->trans[2][1]) * one_vol; - box->trans_inv[2][2] = (box->trans[0][0]*box->trans[1][1] - - box->trans[0][1]*box->trans[1][0]) * one_vol; + real one_vol; + + box->volume = + box->box[0][0] * (box->box[1][1] * box->box[2][2] - + box->box[2][1] * box->box[2][1]) + + box->box[0][1] * (box->box[2][0] * box->box[1][2] - + box->box[1][0] * box->box[2][2]) + + box->box[0][2] * (box->box[1][0] * box->box[2][1] - + box->box[2][0] * box->box[1][1]); + + one_vol = 1.0 / box->volume; + + box->box_inv[0][0] = (box->box[1][1] * box->box[2][2] - + box->box[1][2] * box->box[2][1]) * one_vol; + box->box_inv[0][1] = (box->box[0][2] * box->box[2][1] - + box->box[0][1] * box->box[2][2]) * one_vol; + box->box_inv[0][2] = (box->box[0][1] * box->box[1][2] - + box->box[0][2] * box->box[1][1]) * one_vol; + + box->box_inv[1][0] = (box->box[1][2] * box->box[2][0] - + box->box[1][0] * box->box[2][2]) * one_vol; + box->box_inv[1][1] = (box->box[0][0] * box->box[2][2] - + box->box[0][2] * box->box[2][0]) * one_vol; + box->box_inv[1][2] = (box->box[0][2] * box->box[1][0] - + box->box[0][0] * box->box[1][2]) * one_vol; + + box->box_inv[2][0] = (box->box[1][0] * box->box[2][1] - + box->box[1][1] * box->box[2][0]) * one_vol; + box->box_inv[2][1] = (box->box[0][1] * box->box[2][0] - + box->box[0][0] * box->box[2][1]) * one_vol; + box->box_inv[2][2] = (box->box[0][0] * box->box[1][1] - + box->box[0][1] * box->box[1][0]) * one_vol; + + box->box_norms[0] = SQRT( SQR(box->box[0][0]) + + SQR(box->box[0][1]) + + SQR(box->box[0][2]) ); + box->box_norms[1] = SQRT( SQR(box->box[1][0]) + + SQR(box->box[1][1]) + + SQR(box->box[1][2]) ); + box->box_norms[2] = SQRT( SQR(box->box[2][0]) + + SQR(box->box[2][1]) + + SQR(box->box[2][2]) ); + + box->trans[0][0] = box->box[0][0] / box->box_norms[0]; + box->trans[0][1] = box->box[1][0] / box->box_norms[0]; + box->trans[0][2] = box->box[2][0] / box->box_norms[0]; + + box->trans[1][0] = box->box[0][1] / box->box_norms[1]; + box->trans[1][1] = box->box[1][1] / box->box_norms[1]; + box->trans[1][2] = box->box[2][1] / box->box_norms[1]; + + box->trans[2][0] = box->box[0][2] / box->box_norms[2]; + box->trans[2][1] = box->box[1][2] / box->box_norms[2]; + box->trans[2][2] = box->box[2][2] / box->box_norms[2]; + + one_vol = box->box_norms[0] * box->box_norms[1] * box->box_norms[2] * one_vol; + + box->trans_inv[0][0] = (box->trans[1][1] * box->trans[2][2] - + box->trans[1][2] * box->trans[2][1]) * one_vol; + box->trans_inv[0][1] = (box->trans[0][2] * box->trans[2][1] - + box->trans[0][1] * box->trans[2][2]) * one_vol; + box->trans_inv[0][2] = (box->trans[0][1] * box->trans[1][2] - + box->trans[0][2] * box->trans[1][1]) * one_vol; + + box->trans_inv[1][0] = (box->trans[1][2] * box->trans[2][0] - + box->trans[1][0] * box->trans[2][2]) * one_vol; + box->trans_inv[1][1] = (box->trans[0][0] * box->trans[2][2] - + box->trans[0][2] * box->trans[2][0]) * one_vol; + box->trans_inv[1][2] = (box->trans[0][2] * box->trans[1][0] - + box->trans[0][0] * box->trans[1][2]) * one_vol; + + box->trans_inv[2][0] = (box->trans[1][0] * box->trans[2][1] - + box->trans[1][1] * box->trans[2][0]) * one_vol; + box->trans_inv[2][1] = (box->trans[0][1] * box->trans[2][0] - + box->trans[0][0] * box->trans[2][1]) * one_vol; + box->trans_inv[2][2] = (box->trans[0][0] * box->trans[1][1] - + box->trans[0][1] * box->trans[1][0]) * one_vol; // for (i=0; i < 3; i++) // { // for (j=0; j < 3; j++) -// fprintf(stderr,"%lf\t",box->trans[i][j]); +// fprintf(stderr,"%lf\t",box->trans[i][j]); // fprintf(stderr,"\n"); // } // fprintf(stderr,"\n"); // for (i=0; i < 3; i++) // { // for (j=0; j < 3; j++) -// fprintf(stderr,"%lf\t",box->trans_inv[i][j]); +// fprintf(stderr,"%lf\t",box->trans_inv[i][j]); // fprintf(stderr,"\n"); // } - box->g[0][0] = box->box[0][0] * box->box[0][0] + - box->box[0][1] * box->box[0][1] + - box->box[0][2] * box->box[0][2]; - box->g[1][0] = - box->g[0][1] = box->box[0][0] * box->box[1][0] + - box->box[0][1] * box->box[1][1] + - box->box[0][2] * box->box[1][2]; - box->g[2][0] = - box->g[0][2] = box->box[0][0] * box->box[2][0] + - box->box[0][1] * box->box[2][1] + - box->box[0][2] * box->box[2][2]; - - box->g[1][1] = box->box[1][0] * box->box[1][0] + - box->box[1][1] * box->box[1][1] + - box->box[1][2] * box->box[1][2]; - box->g[1][2] = - box->g[2][1] = box->box[1][0] * box->box[2][0] + - box->box[1][1] * box->box[2][1] + - box->box[1][2] * box->box[2][2]; - - box->g[2][2] = box->box[2][0] * box->box[2][0] + - box->box[2][1] * box->box[2][1] + - box->box[2][2] * box->box[2][2]; - - // These proportions are only used for isotropic_NPT! - box->side_prop[0] = box->box[0][0] / box->box[0][0]; - box->side_prop[1] = box->box[1][1] / box->box[0][0]; - box->side_prop[2] = box->box[2][2] / box->box[0][0]; + box->g[0][0] = box->box[0][0] * box->box[0][0] + + box->box[0][1] * box->box[0][1] + + box->box[0][2] * box->box[0][2]; + box->g[1][0] = + box->g[0][1] = box->box[0][0] * box->box[1][0] + + box->box[0][1] * box->box[1][1] + + box->box[0][2] * box->box[1][2]; + box->g[2][0] = + box->g[0][2] = box->box[0][0] * box->box[2][0] + + box->box[0][1] * box->box[2][1] + + box->box[0][2] * box->box[2][2]; + + box->g[1][1] = box->box[1][0] * box->box[1][0] + + box->box[1][1] * box->box[1][1] + + box->box[1][2] * box->box[1][2]; + box->g[1][2] = + box->g[2][1] = box->box[1][0] * box->box[2][0] + + box->box[1][1] * box->box[2][1] + + box->box[1][2] * box->box[2][2]; + + box->g[2][2] = box->box[2][0] * box->box[2][0] + + box->box[2][1] * box->box[2][1] + + box->box[2][2] * box->box[2][2]; + + // These proportions are only used for isotropic_NPT! + box->side_prop[0] = box->box[0][0] / box->box[0][0]; + box->side_prop[1] = box->box[1][1] / box->box[0][0]; + box->side_prop[2] = box->box[2][2] / box->box[0][0]; } void Transform( rvec x1, simulation_box *box, char flag, rvec x2 ) { - int i, j; - real tmp; - - // printf(">x1: (%lf, %lf, %lf)\n",x1[0],x1[1],x1[2]); - - if (flag > 0) { - for (i=0; i < 3; i++) { - tmp = 0.0; - for (j=0; j < 3; j++) - tmp += box->trans[i][j]*x1[j]; - x2[i] = tmp; + int i, j; + real tmp; + + // printf(">x1: (%lf, %lf, %lf)\n",x1[0],x1[1],x1[2]); + + if (flag > 0) + { + for (i = 0; i < 3; i++) + { + tmp = 0.0; + for (j = 0; j < 3; j++) + tmp += box->trans[i][j] * x1[j]; + x2[i] = tmp; + } } - } - else { - for (i=0; i < 3; i++) { - tmp = 0.0; - for (j=0; j < 3; j++) - tmp += box->trans_inv[i][j]*x1[j]; - x2[i] = tmp; + else + { + for (i = 0; i < 3; i++) + { + tmp = 0.0; + for (j = 0; j < 3; j++) + tmp += box->trans_inv[i][j] * x1[j]; + x2[i] = tmp; + } } - } - // printf(">x2: (%lf, %lf, %lf)\n", x2[0], x2[1], x2[2]); + // printf(">x2: (%lf, %lf, %lf)\n", x2[0], x2[1], x2[2]); } void Transform_to_UnitBox( rvec x1, simulation_box *box, char flag, rvec x2 ) { - Transform( x1, box, flag, x2 ); - - x2[0] /= box->box_norms[0]; - x2[1] /= box->box_norms[1]; - x2[2] /= box->box_norms[2]; + Transform( x1, box, flag, x2 ); + + x2[0] /= box->box_norms[0]; + x2[1] /= box->box_norms[1]; + x2[2] /= box->box_norms[2]; } void Inc_on_T3( rvec x, rvec dx, simulation_box *box ) { - int i; - real tmp; + int i; + real tmp; - for (i=0; i < 3; i++) { - tmp = x[i] + dx[i]; - if( tmp <= -box->box_norms[i] || tmp >= box->box_norms[i] ) - tmp = fmod( tmp, box->box_norms[i] ); + for (i = 0; i < 3; i++) + { + tmp = x[i] + dx[i]; + if ( tmp <= -box->box_norms[i] || tmp >= box->box_norms[i] ) + tmp = fmod( tmp, box->box_norms[i] ); - if( tmp < 0 ) tmp += box->box_norms[i]; - x[i] = tmp; - } + if ( tmp < 0 ) tmp += box->box_norms[i]; + x[i] = tmp; + } } real Sq_Distance_on_T3(rvec x1, rvec x2, simulation_box* box, rvec r) { - real norm=0.0; - real d, tmp; - int i; - - for (i=0; i < 3; i++) { - d = x2[i] - x1[i]; - tmp = SQR(d); - - if( tmp >= SQR( box->box_norms[i] / 2.0 ) ) { - if (x2[i] > x1[i]) - d -= box->box_norms[i]; - else - d += box->box_norms[i]; - - r[i] = d; - norm += SQR(d); + real norm = 0.0; + real d, tmp; + int i; + + for (i = 0; i < 3; i++) + { + d = x2[i] - x1[i]; + tmp = SQR(d); + + if ( tmp >= SQR( box->box_norms[i] / 2.0 ) ) + { + if (x2[i] > x1[i]) + d -= box->box_norms[i]; + else + d += box->box_norms[i]; + + r[i] = d; + norm += SQR(d); + } + else + { + r[i] = d; + norm += tmp; + } } - else { - r[i] = d; - norm += tmp; - } - } - - return norm; + + return norm; } void Distance_on_T3_Gen( rvec x1, rvec x2, simulation_box* box, rvec r ) { - rvec xa, xb, ra; + rvec xa, xb, ra; + + Transform( x1, box, -1, xa ); + Transform( x2, box, -1, xb ); - Transform( x1, box, -1, xa ); - Transform( x2, box, -1, xb ); + //printf(">xa: (%lf, %lf, %lf)\n",xa[0],xa[1],xa[2]); + //printf(">xb: (%lf, %lf, %lf)\n",xb[0],xb[1],xb[2]); - //printf(">xa: (%lf, %lf, %lf)\n",xa[0],xa[1],xa[2]); - //printf(">xb: (%lf, %lf, %lf)\n",xb[0],xb[1],xb[2]); - - Sq_Distance_on_T3( xa, xb, box, ra ); + Sq_Distance_on_T3( xa, xb, box, ra ); - Transform( ra, box, 1, r ); + Transform( ra, box, 1, r ); } void Inc_on_T3_Gen( rvec x, rvec dx, simulation_box* box ) { - rvec xa, dxa; + rvec xa, dxa; - Transform( x, box, -1, xa ); - Transform( dx, box, -1, dxa ); + Transform( x, box, -1, xa ); + Transform( dx, box, -1, dxa ); - //printf(">xa: (%lf, %lf, %lf)\n",xa[0],xa[1],xa[2]); - //printf(">dxa: (%lf, %lf, %lf)\n",dxa[0],dxa[1],dxa[2]); - - Inc_on_T3( xa, dxa, box ); + //printf(">xa: (%lf, %lf, %lf)\n",xa[0],xa[1],xa[2]); + //printf(">dxa: (%lf, %lf, %lf)\n",dxa[0],dxa[1],dxa[2]); - //printf(">new_xa: (%lf, %lf, %lf)\n",xa[0],xa[1],xa[2]); + Inc_on_T3( xa, dxa, box ); - Transform( xa, box, 1, x ); + //printf(">new_xa: (%lf, %lf, %lf)\n",xa[0],xa[1],xa[2]); + + Transform( xa, box, 1, x ); } real Metric_Product( rvec x1, rvec x2, simulation_box* box ) { - int i, j; - real dist=0.0, tmp; + int i, j; + real dist = 0.0, tmp; - for( i = 0; i < 3; i++ ) + for ( i = 0; i < 3; i++ ) { - tmp = 0.0; - for( j = 0; j < 3; j++ ) - tmp += box->g[i][j] * x2[j]; - dist += x1[i] * tmp; + tmp = 0.0; + for ( j = 0; j < 3; j++ ) + tmp += box->g[i][j] * x2[j]; + dist += x1[i] * tmp; } - return dist; + return dist; } -int Are_Far_Neighbors( rvec x1, rvec x2, simulation_box *box, - real cutoff, far_neighbor_data *data ) +int Are_Far_Neighbors( rvec x1, rvec x2, simulation_box *box, + real cutoff, far_neighbor_data *data ) { - real norm_sqr, d, tmp; - int i; - - norm_sqr = 0; - - for( i = 0; i < 3; i++ ) { - d = x2[i] - x1[i]; - tmp = SQR(d); - - if( tmp >= SQR( box->box_norms[i] / 2.0 ) ) { - if( x2[i] > x1[i] ) { - d -= box->box_norms[i]; - data->rel_box[i] = -1; - } - else { - d += box->box_norms[i]; - data->rel_box[i] = +1; - } - - data->dvec[i] = d; - norm_sqr += SQR(d); + real norm_sqr, d, tmp; + int i; + + norm_sqr = 0; + + for ( i = 0; i < 3; i++ ) + { + d = x2[i] - x1[i]; + tmp = SQR(d); + + if ( tmp >= SQR( box->box_norms[i] / 2.0 ) ) + { + if ( x2[i] > x1[i] ) + { + d -= box->box_norms[i]; + data->rel_box[i] = -1; + } + else + { + d += box->box_norms[i]; + data->rel_box[i] = +1; + } + + data->dvec[i] = d; + norm_sqr += SQR(d); + } + else + { + data->dvec[i] = d; + norm_sqr += tmp; + data->rel_box[i] = 0; + } } - else { - data->dvec[i] = d; - norm_sqr += tmp; - data->rel_box[i] = 0; - } - } - - if( norm_sqr <= SQR(cutoff) ){ - data->d = sqrt(norm_sqr); - return 1; - } - - return 0; + + if ( norm_sqr <= SQR(cutoff) ) + { + data->d = sqrt(norm_sqr); + return 1; + } + + return 0; } -/* Determines if the distance between x1 and x2 is < vlist_cut. +/* Determines if the distance between x1 and x2 is < vlist_cut. If so, this neighborhood is added to the list of far neighbors. Periodic boundary conditions do not apply. */ -void Get_NonPeriodic_Far_Neighbors( rvec x1, rvec x2, simulation_box *box, - control_params *control, - far_neighbor_data *new_nbrs, int *count ) +void Get_NonPeriodic_Far_Neighbors( rvec x1, rvec x2, simulation_box *box, + control_params *control, + far_neighbor_data *new_nbrs, int *count ) { - real norm_sqr; - - rvec_ScaledSum( new_nbrs[0].dvec, 1.0, x2, -1.0, x1 ); - - norm_sqr = rvec_Norm_Sqr( new_nbrs[0].dvec ); - - if( norm_sqr <= SQR( control->vlist_cut ) ) { - *count = 1; - new_nbrs[0].d = SQRT( norm_sqr ); - - ivec_MakeZero( new_nbrs[0].rel_box ); - // rvec_MakeZero( new_nbrs[0].ext_factor ); - } - else *count = 0; + real norm_sqr; + + rvec_ScaledSum( new_nbrs[0].dvec, 1.0, x2, -1.0, x1 ); + + norm_sqr = rvec_Norm_Sqr( new_nbrs[0].dvec ); + + if ( norm_sqr <= SQR( control->vlist_cut ) ) + { + *count = 1; + new_nbrs[0].d = SQRT( norm_sqr ); + + ivec_MakeZero( new_nbrs[0].rel_box ); + // rvec_MakeZero( new_nbrs[0].ext_factor ); + } + else *count = 0; } /* Finds periodic neighbors in a 'big_box'. Here 'big_box' means: the current simulation box has all dimensions > 2 *vlist_cut. - If the periodic distance between x1 and x2 is than vlist_cut, this + If the periodic distance between x1 and x2 is than vlist_cut, this neighborhood is added to the list of far neighbors. */ -void Get_Periodic_Far_Neighbors_Big_Box( rvec x1, rvec x2, simulation_box *box, - control_params *control, - far_neighbor_data *periodic_nbrs, - int *count ) +void Get_Periodic_Far_Neighbors_Big_Box( rvec x1, rvec x2, simulation_box *box, + control_params *control, + far_neighbor_data *periodic_nbrs, + int *count ) { - real norm_sqr, d, tmp; - int i; - - norm_sqr = 0; - - for( i = 0; i < 3; i++ ) { - d = x2[i] - x1[i]; - tmp = SQR(d); - // fprintf(out,"Inside Sq_Distance_on_T3, %d, %lf, %lf\n", - // i,tmp,SQR(box->box_norms[i]/2.0)); - - if( tmp >= SQR( box->box_norms[i] / 2.0 ) ) { - if( x2[i] > x1[i] ) { - d -= box->box_norms[i]; - periodic_nbrs[0].rel_box[i] = -1; - // periodic_nbrs[0].ext_factor[i] = +1; - } - else { - d += box->box_norms[i]; - periodic_nbrs[0].rel_box[i] = +1; - // periodic_nbrs[0].ext_factor[i] = -1; - } - - periodic_nbrs[0].dvec[i] = d; - norm_sqr += SQR(d); + real norm_sqr, d, tmp; + int i; + + norm_sqr = 0; + + for ( i = 0; i < 3; i++ ) + { + d = x2[i] - x1[i]; + tmp = SQR(d); + // fprintf(out,"Inside Sq_Distance_on_T3, %d, %lf, %lf\n", + // i,tmp,SQR(box->box_norms[i]/2.0)); + + if ( tmp >= SQR( box->box_norms[i] / 2.0 ) ) + { + if ( x2[i] > x1[i] ) + { + d -= box->box_norms[i]; + periodic_nbrs[0].rel_box[i] = -1; + // periodic_nbrs[0].ext_factor[i] = +1; + } + else + { + d += box->box_norms[i]; + periodic_nbrs[0].rel_box[i] = +1; + // periodic_nbrs[0].ext_factor[i] = -1; + } + + periodic_nbrs[0].dvec[i] = d; + norm_sqr += SQR(d); + } + else + { + periodic_nbrs[0].dvec[i] = d; + norm_sqr += tmp; + periodic_nbrs[0].rel_box[i] = 0; + // periodic_nbrs[0].ext_factor[i] = 0; + } + } + + if ( norm_sqr <= SQR( control->vlist_cut ) ) + { + *count = 1; + periodic_nbrs[0].d = SQRT( norm_sqr ); } - else { - periodic_nbrs[0].dvec[i] = d; - norm_sqr += tmp; - periodic_nbrs[0].rel_box[i] = 0; - // periodic_nbrs[0].ext_factor[i] = 0; - } - } - - if( norm_sqr <= SQR( control->vlist_cut ) ) { - *count = 1; - periodic_nbrs[0].d = SQRT( norm_sqr ); - } - else *count = 0; + else *count = 0; } -/* Finds all periodic far neighborhoods between x1 and x2 +/* Finds all periodic far neighborhoods between x1 and x2 ((dist(x1, x2') < vlist_cut, periodic images of x2 are also considered). Here the box is 'small' meaning that at least one dimension is < 2*vlist_cut. - IMPORTANT: This part might need some improvement. In NPT, the simulation box - might get too small (such as <5 A!). In this case we have to consider the + IMPORTANT: This part might need some improvement. In NPT, the simulation box + might get too small (such as <5 A!). In this case we have to consider the periodic images of x2 that are two boxs away!!! */ void Get_Periodic_Far_Neighbors_Small_Box( rvec x1, rvec x2, simulation_box *box, - control_params *control, - far_neighbor_data *periodic_nbrs, - int *count ) + control_params *control, + far_neighbor_data *periodic_nbrs, + int *count ) { - int i, j, k; - int imax, jmax, kmax; - real sqr_norm, d_i, d_j, d_k; - - *count = 0; - /* determine the max stretch of imaginary boxs in each direction - to handle periodic boundary conditions correctly. */ - imax = (int)(control->vlist_cut / box->box_norms[0] + 1); - jmax = (int)(control->vlist_cut / box->box_norms[1] + 1); - kmax = (int)(control->vlist_cut / box->box_norms[2] + 1); - /*if( imax > 1 || jmax > 1 || kmax > 1 ) - fprintf( stderr, "box %8.3f x %8.3f x %8.3f --> %2d %2d %2d\n", - box->box_norms[0], box->box_norms[1], box->box_norms[2], - imax, jmax, kmax ); */ - - - for( i = -imax; i <= imax; ++i ) - if(fabs(d_i=((x2[0]+i*box->box_norms[0])-x1[0]))<=control->vlist_cut) { - for( j = -jmax; j <= jmax; ++j ) - if(fabs(d_j=((x2[1]+j*box->box_norms[1])-x1[1]))<=control->vlist_cut) { - for( k = -kmax; k <= kmax; ++k ) - if(fabs(d_k=((x2[2]+k*box->box_norms[2])-x1[2]))<=control->vlist_cut) { - sqr_norm = SQR(d_i) + SQR(d_j) + SQR(d_k); - if( sqr_norm <= SQR(control->vlist_cut) ) { - periodic_nbrs[ *count ].d = SQRT( sqr_norm ); - - periodic_nbrs[ *count ].dvec[0] = d_i; - periodic_nbrs[ *count ].dvec[1] = d_j; - periodic_nbrs[ *count ].dvec[2] = d_k; - - periodic_nbrs[ *count ].rel_box[0] = i; - periodic_nbrs[ *count ].rel_box[1] = j; - periodic_nbrs[ *count ].rel_box[2] = k; - - /* if( i || j || k ) { - fprintf(stderr, "x1: %.2f %.2f %.2f\n", x1[0], x1[1], x1[2]); - fprintf(stderr, "x2: %.2f %.2f %.2f\n", x2[0], x2[1], x2[2]); - fprintf( stderr, "d : %8.2f%8.2f%8.2f\n\n", d_i, d_j, d_k ); - } */ - - /* if(i) periodic_nbrs[*count].ext_factor[0] = (real)i/-abs(i); - else periodic_nbrs[*count].ext_factor[0] = 0; - - if(j) periodic_nbrs[*count].ext_factor[1] = (real)j/-abs(j); - else periodic_nbrs[*count].ext_factor[1] = 0; - - if(k) periodic_nbrs[*count].ext_factor[2] = (real)k/-abs(k); - else periodic_nbrs[*count].ext_factor[2] = 0; */ - - - /* if( i == 0 && j == 0 && k == 0 ) - * periodic_nbrs[ *count ].imaginary = 0; - * else periodic_nbrs[ *count ].imaginary = 1; - */ - ++(*count); - } - } - } - } + int i, j, k; + int imax, jmax, kmax; + real sqr_norm, d_i, d_j, d_k; + + *count = 0; + /* determine the max stretch of imaginary boxs in each direction + to handle periodic boundary conditions correctly. */ + imax = (int)(control->vlist_cut / box->box_norms[0] + 1); + jmax = (int)(control->vlist_cut / box->box_norms[1] + 1); + kmax = (int)(control->vlist_cut / box->box_norms[2] + 1); + /*if( imax > 1 || jmax > 1 || kmax > 1 ) + fprintf( stderr, "box %8.3f x %8.3f x %8.3f --> %2d %2d %2d\n", + box->box_norms[0], box->box_norms[1], box->box_norms[2], + imax, jmax, kmax ); */ + + + for ( i = -imax; i <= imax; ++i ) + if (fabs(d_i = ((x2[0] + i * box->box_norms[0]) - x1[0])) <= control->vlist_cut) + { + for ( j = -jmax; j <= jmax; ++j ) + if (fabs(d_j = ((x2[1] + j * box->box_norms[1]) - x1[1])) <= control->vlist_cut) + { + for ( k = -kmax; k <= kmax; ++k ) + if (fabs(d_k = ((x2[2] + k * box->box_norms[2]) - x1[2])) <= control->vlist_cut) + { + sqr_norm = SQR(d_i) + SQR(d_j) + SQR(d_k); + if ( sqr_norm <= SQR(control->vlist_cut) ) + { + periodic_nbrs[ *count ].d = SQRT( sqr_norm ); + + periodic_nbrs[ *count ].dvec[0] = d_i; + periodic_nbrs[ *count ].dvec[1] = d_j; + periodic_nbrs[ *count ].dvec[2] = d_k; + + periodic_nbrs[ *count ].rel_box[0] = i; + periodic_nbrs[ *count ].rel_box[1] = j; + periodic_nbrs[ *count ].rel_box[2] = k; + + /* if( i || j || k ) { + fprintf(stderr, "x1: %.2f %.2f %.2f\n", x1[0], x1[1], x1[2]); + fprintf(stderr, "x2: %.2f %.2f %.2f\n", x2[0], x2[1], x2[2]); + fprintf( stderr, "d : %8.2f%8.2f%8.2f\n\n", d_i, d_j, d_k ); + } */ + + /* if(i) periodic_nbrs[*count].ext_factor[0] = (real)i/-abs(i); + else periodic_nbrs[*count].ext_factor[0] = 0; + + if(j) periodic_nbrs[*count].ext_factor[1] = (real)j/-abs(j); + else periodic_nbrs[*count].ext_factor[1] = 0; + + if(k) periodic_nbrs[*count].ext_factor[2] = (real)k/-abs(k); + else periodic_nbrs[*count].ext_factor[2] = 0; */ + + + /* if( i == 0 && j == 0 && k == 0 ) + * periodic_nbrs[ *count ].imaginary = 0; + * else periodic_nbrs[ *count ].imaginary = 1; + */ + ++(*count); + } + } + } + } } - + /* Returns the mapping for the neighbor box pointed by (ix,iy,iz) */ /*int Get_Nbr_Box( simulation_box *box, int ix, int iy, int iz ) { - return (9 * ix + 3 * iy + iz + 13); + return (9 * ix + 3 * iy + iz + 13); // 13 is to handle negative indexes properly }*/ @@ -566,7 +591,7 @@ void Get_Periodic_Far_Neighbors_Small_Box( rvec x1, rvec x2, simulation_box *box { int map; - map = 9 * ix + 3 * iy + iz + 13; + map = 9 * ix + 3 * iy + iz + 13; // 13 is to adjust -1,-1,-1 correspond to index 0 return box->nbr_box_press[map]; @@ -577,10 +602,10 @@ void Get_Periodic_Far_Neighbors_Small_Box( rvec x1, rvec x2, simulation_box *box /*void Inc_Nbr_Box_Press( simulation_box *box, int ix, int iy, int iz, rvec v ) { int map; - - map = 9 * ix + 3 * iy + iz + 13; + + map = 9 * ix + 3 * iy + iz + 13; // 13 is to adjust -1,-1,-1 correspond to index 0 - + rvec_Add( box->nbr_box_press[map], v ); }*/ @@ -594,39 +619,39 @@ void Get_Periodic_Far_Neighbors_Small_Box( rvec x1, rvec x2, simulation_box *box void Print_Box_Information( simulation_box* box, FILE *out ) { - int i, j; + int i, j; - fprintf( out, "box: {" ); - for( i = 0; i < 3; ++i ) + fprintf( out, "box: {" ); + for ( i = 0; i < 3; ++i ) { - fprintf( out, "{" ); - for( j = 0; j < 3; ++j ) - fprintf( out, "%8.3f ", box->box[i][j] ); - fprintf( out, "}" ); + fprintf( out, "{" ); + for ( j = 0; j < 3; ++j ) + fprintf( out, "%8.3f ", box->box[i][j] ); + fprintf( out, "}" ); } - fprintf( out, "}\n" ); + fprintf( out, "}\n" ); - fprintf( out, "V: %8.3f\tdims: {%8.3f, %8.3f, %8.3f}\n", - box->volume, - box->box_norms[0], box->box_norms[1], box->box_norms[2] ); + fprintf( out, "V: %8.3f\tdims: {%8.3f, %8.3f, %8.3f}\n", + box->volume, + box->box_norms[0], box->box_norms[1], box->box_norms[2] ); - fprintf( out, "box_trans: {" ); - for( i = 0; i < 3; ++i ) + fprintf( out, "box_trans: {" ); + for ( i = 0; i < 3; ++i ) { - fprintf( out, "{" ); - for( j = 0; j < 3; ++j ) - fprintf( out, "%8.3f ", box->trans[i][j] ); - fprintf( out, "}" ); + fprintf( out, "{" ); + for ( j = 0; j < 3; ++j ) + fprintf( out, "%8.3f ", box->trans[i][j] ); + fprintf( out, "}" ); } - fprintf( out, "}\n" ); + fprintf( out, "}\n" ); - fprintf( out, "box_trinv: {" ); - for( i = 0; i < 3; ++i ) + fprintf( out, "box_trinv: {" ); + for ( i = 0; i < 3; ++i ) { - fprintf( out, "{" ); - for( j = 0; j < 3; ++j ) - fprintf( out, "%8.3f ", box->trans_inv[i][j] ); - fprintf( out, "}" ); + fprintf( out, "{" ); + for ( j = 0; j < 3; ++j ) + fprintf( out, "%8.3f ", box->trans_inv[i][j] ); + fprintf( out, "}" ); } - fprintf( out, "}\n" ); + fprintf( out, "}\n" ); } diff --git a/puremd_rc_1003/sPuReMD/box.h b/puremd_rc_1003/sPuReMD/box.h index 88a2147a..de3e33de 100644 --- a/puremd_rc_1003/sPuReMD/box.h +++ b/puremd_rc_1003/sPuReMD/box.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -25,33 +25,33 @@ #include "mytypes.h" /* Initializes box from CRYST1 line of PDB */ -void Init_Box_From_CRYST(real, real, real, real, real, real, - simulation_box*/*, int*/); +void Init_Box_From_CRYST(real, real, real, real, real, real, + simulation_box*/*, int*/); /* Initializes box from box rtensor */ void Update_Box(rtensor, simulation_box* /*, int*/); void Update_Box_Isotropic(simulation_box*, real /*, int*/); void Update_Box_SemiIsotropic( simulation_box*, rvec /*, int*/ ); -/* Computes all the transformations, +/* Computes all the transformations, metric and other quantities from box rtensor */ void Make_Consistent(simulation_box*/*, int*/ ); -/* Applies transformation to and from +/* Applies transformation to and from Cartesian to Triclinic coordinates based on flag */ /* Use -1 flag for Cartesian -> Triclinic and +1 for otherway */ void Transform( rvec, simulation_box*, char, rvec ); void Transform_to_UnitBox( rvec, simulation_box*, char, rvec ); int Are_Far_Neighbors( rvec, rvec, simulation_box*, real, far_neighbor_data* ); -void Get_NonPeriodic_Far_Neighbors( rvec, rvec, simulation_box*, - control_params*, far_neighbor_data*, int* ); -void Get_Periodic_Far_Neighbors_Big_Box( rvec, rvec, simulation_box*, - control_params*, far_neighbor_data*, - int* ); -void Get_Periodic_Far_Neighbors_Small_Box( rvec, rvec, simulation_box*, - control_params*, far_neighbor_data*, - int* ); +void Get_NonPeriodic_Far_Neighbors( rvec, rvec, simulation_box*, + control_params*, far_neighbor_data*, int* ); +void Get_Periodic_Far_Neighbors_Big_Box( rvec, rvec, simulation_box*, + control_params*, far_neighbor_data*, + int* ); +void Get_Periodic_Far_Neighbors_Small_Box( rvec, rvec, simulation_box*, + control_params*, far_neighbor_data*, + int* ); void Distance_on_T3_Gen( rvec, rvec, simulation_box*, rvec ); void Inc_on_T3_Gen( rvec, rvec, simulation_box* ); diff --git a/puremd_rc_1003/sPuReMD/forces.c b/puremd_rc_1003/sPuReMD/forces.c index 195008af..ae6128c6 100644 --- a/puremd_rc_1003/sPuReMD/forces.c +++ b/puremd_rc_1003/sPuReMD/forces.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -33,854 +33,906 @@ #include "vector.h" -void Dummy_Interaction( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Dummy_Interaction( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { } void Init_Bonded_Force_Functions( control_params *control ) -{ - Interaction_Functions[0] = Calculate_Bond_Orders; - Interaction_Functions[1] = Bond_Energy; //*/Dummy_Interaction; - Interaction_Functions[2] = LonePair_OverUnder_Coordination_Energy; - //*/Dummy_Interaction; - Interaction_Functions[3] = Three_Body_Interactions; //*/Dummy_Interaction; - Interaction_Functions[4] = Four_Body_Interactions; //*/Dummy_Interaction; - if( control->hb_cut > 0 ) - Interaction_Functions[5] = Hydrogen_Bonds; //*/Dummy_Interaction; - else Interaction_Functions[5] = Dummy_Interaction; - Interaction_Functions[6] = Dummy_Interaction; //empty - Interaction_Functions[7] = Dummy_Interaction; //empty - Interaction_Functions[8] = Dummy_Interaction; //empty - Interaction_Functions[9] = Dummy_Interaction; //empty +{ + Interaction_Functions[0] = Calculate_Bond_Orders; + Interaction_Functions[1] = Bond_Energy; //*/Dummy_Interaction; + Interaction_Functions[2] = LonePair_OverUnder_Coordination_Energy; + //*/Dummy_Interaction; + Interaction_Functions[3] = Three_Body_Interactions; //*/Dummy_Interaction; + Interaction_Functions[4] = Four_Body_Interactions; //*/Dummy_Interaction; + if ( control->hb_cut > 0 ) + Interaction_Functions[5] = Hydrogen_Bonds; //*/Dummy_Interaction; + else Interaction_Functions[5] = Dummy_Interaction; + Interaction_Functions[6] = Dummy_Interaction; //empty + Interaction_Functions[7] = Dummy_Interaction; //empty + Interaction_Functions[8] = Dummy_Interaction; //empty + Interaction_Functions[9] = Dummy_Interaction; //empty } -void Compute_Bonded_Forces( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Compute_Bonded_Forces( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i; - // real t_start, t_end, t_elapsed; + int i; + // real t_start, t_end, t_elapsed; #ifdef TEST_ENERGY - /* Mark beginning of a new timestep in each energy file */ - fprintf( out_control->ebond, "step: %d\n%6s%6s%12s%12s%12s\n", - data->step, "atom1", "atom2", "bo", "ebond", "total" ); - fprintf( out_control->elp, "step: %d\n%6s%12s%12s%12s\n", - data->step, "atom", "nlp", "elp", "total" ); - fprintf( out_control->eov, "step: %d\n%6s%12s%12s\n", - data->step, "atom", "eov", "total" ); - fprintf( out_control->eun, "step: %d\n%6s%12s%12s\n", - data->step, "atom", "eun", "total" ); - fprintf( out_control->eval, "step: %d\n%6s%6s%6s%12s%12s%12s%12s%12s%12s\n", - data->step, "atom1", "atom2", "atom3", - "angle", "bo(12)", "bo(23)", "eval", "epen", "total" ); - fprintf( out_control->epen, "step: %d\n%6s%6s%6s%12s%12s%12s%12s%12s\n", - data->step, "atom1", "atom2", "atom3", - "angle", "bo(12)", "bo(23)", "epen", "total" ); - fprintf( out_control->ecoa, "step: %d\n%6s%6s%6s%12s%12s%12s%12s%12s\n", - data->step, "atom1", "atom2", "atom3", - "angle", "bo(12)", "bo(23)", "ecoa", "total" ); - fprintf( out_control->ehb, "step: %d\n%6s%6s%6s%12s%12s%12s%12s%12s\n", - data->step, "atom1", "atom2", "atom3", - "r(23)", "angle", "bo(12)", "ehb", "total" ); - fprintf( out_control->etor, "step: %d\n%6s%6s%6s%6s%12s%12s%12s%12s\n", - data->step, "atom1", "atom2", "atom3", "atom4", - "phi", "bo(23)", "etor", "total" ); - fprintf( out_control->econ, "step:%d\n%6s%6s%6s%6s%12s%12s%12s%12s%12s%12s\n", - data->step, "atom1", "atom2", "atom3", "atom4", - "phi", "bo(12)", "bo(23)", "bo(34)", "econ", "total" ); -#endif - - /* Implement all the function calls as function pointers */ - for( i = 0; i < NO_OF_INTERACTIONS; i++ ) { - (Interaction_Functions[i])(system, control, data, workspace, - lists, out_control); + /* Mark beginning of a new timestep in each energy file */ + fprintf( out_control->ebond, "step: %d\n%6s%6s%12s%12s%12s\n", + data->step, "atom1", "atom2", "bo", "ebond", "total" ); + fprintf( out_control->elp, "step: %d\n%6s%12s%12s%12s\n", + data->step, "atom", "nlp", "elp", "total" ); + fprintf( out_control->eov, "step: %d\n%6s%12s%12s\n", + data->step, "atom", "eov", "total" ); + fprintf( out_control->eun, "step: %d\n%6s%12s%12s\n", + data->step, "atom", "eun", "total" ); + fprintf( out_control->eval, "step: %d\n%6s%6s%6s%12s%12s%12s%12s%12s%12s\n", + data->step, "atom1", "atom2", "atom3", + "angle", "bo(12)", "bo(23)", "eval", "epen", "total" ); + fprintf( out_control->epen, "step: %d\n%6s%6s%6s%12s%12s%12s%12s%12s\n", + data->step, "atom1", "atom2", "atom3", + "angle", "bo(12)", "bo(23)", "epen", "total" ); + fprintf( out_control->ecoa, "step: %d\n%6s%6s%6s%12s%12s%12s%12s%12s\n", + data->step, "atom1", "atom2", "atom3", + "angle", "bo(12)", "bo(23)", "ecoa", "total" ); + fprintf( out_control->ehb, "step: %d\n%6s%6s%6s%12s%12s%12s%12s%12s\n", + data->step, "atom1", "atom2", "atom3", + "r(23)", "angle", "bo(12)", "ehb", "total" ); + fprintf( out_control->etor, "step: %d\n%6s%6s%6s%6s%12s%12s%12s%12s\n", + data->step, "atom1", "atom2", "atom3", "atom4", + "phi", "bo(23)", "etor", "total" ); + fprintf( out_control->econ, "step:%d\n%6s%6s%6s%6s%12s%12s%12s%12s%12s%12s\n", + data->step, "atom1", "atom2", "atom3", "atom4", + "phi", "bo(12)", "bo(23)", "bo(34)", "econ", "total" ); +#endif + + /* Implement all the function calls as function pointers */ + for ( i = 0; i < NO_OF_INTERACTIONS; i++ ) + { + (Interaction_Functions[i])(system, control, data, workspace, + lists, out_control); #if defined(DEBUG_FOCUS) - fprintf( stderr, "f%d-", i ); + fprintf( stderr, "f%d-", i ); #endif #ifdef TEST_FORCES - (Print_Interactions[i])(system, control, data, workspace, - lists, out_control); + (Print_Interactions[i])(system, control, data, workspace, + lists, out_control); #endif - } + } } -void Compute_NonBonded_Forces( reax_system *system, control_params *control, - simulation_data *data,static_storage *workspace, - list** lists, output_controls *out_control ) +void Compute_NonBonded_Forces( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list** lists, output_controls *out_control ) { - real t_start, t_elapsed; + real t_start, t_elapsed; #ifdef TEST_ENERGY - fprintf( out_control->evdw, "step: %d\n%6s%6s%12s%12s%12s\n", - data->step, "atom1", "atom2", "r12", "evdw", "total" ); - fprintf( out_control->ecou, "step: %d\n%6s%6s%12s%12s%12s%12s%12s\n", - data->step, "atom1", "atom2", "r12", "q1", "q2", "ecou", "total" ); + fprintf( out_control->evdw, "step: %d\n%6s%6s%12s%12s%12s\n", + data->step, "atom1", "atom2", "r12", "evdw", "total" ); + fprintf( out_control->ecou, "step: %d\n%6s%6s%12s%12s%12s%12s%12s\n", + data->step, "atom1", "atom2", "r12", "q1", "q2", "ecou", "total" ); #endif - t_start = Get_Time( ); - QEq( system, control, data, workspace, lists[FAR_NBRS], out_control ); - t_elapsed = Get_Timing_Info( t_start ); - data->timing.QEq += t_elapsed; + t_start = Get_Time( ); + QEq( system, control, data, workspace, lists[FAR_NBRS], out_control ); + t_elapsed = Get_Timing_Info( t_start ); + data->timing.QEq += t_elapsed; #if defined(DEBUG_FOCUS) - fprintf( stderr, "qeq - " ); + fprintf( stderr, "qeq - " ); #endif - if ( control->tabulate == 0) - vdW_Coulomb_Energy( system, control, data, workspace, lists, out_control ); - else - Tabulated_vdW_Coulomb_Energy( system, control, data, workspace, - lists, out_control ); + if ( control->tabulate == 0) + vdW_Coulomb_Energy( system, control, data, workspace, lists, out_control ); + else + Tabulated_vdW_Coulomb_Energy( system, control, data, workspace, + lists, out_control ); #if defined(DEBUG_FOCUS) - fprintf( stderr, "nonb forces - " ); + fprintf( stderr, "nonb forces - " ); #endif #ifdef TEST_FORCES - Print_vdW_Coulomb_Forces( system, control, data, workspace, - lists, out_control ); + Print_vdW_Coulomb_Forces( system, control, data, workspace, + lists, out_control ); #endif } -/* This version of Compute_Total_Force computes forces from coefficients +/* This version of Compute_Total_Force computes forces from coefficients accumulated by all interaction functions. Saves enormous time & space! */ -void Compute_Total_Force( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists ) +void Compute_Total_Force( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists ) { - int i, pj; - list *bonds = (*lists) + BONDS; - - for( i = 0; i < system->N; ++i ) - for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) - if( i < bonds->select.bond_list[pj].nbr ) { - if( control->ensemble == NVE || control->ensemble == NVT || control->ensemble == bNVT) - Add_dBond_to_Forces( i, pj, system, data, workspace, lists ); - else - Add_dBond_to_Forces_NPT( i, pj, system, data, workspace, lists ); - } + int i, pj; + list *bonds = (*lists) + BONDS; + + for ( i = 0; i < system->N; ++i ) + for ( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) + if ( i < bonds->select.bond_list[pj].nbr ) + { + if ( control->ensemble == NVE || control->ensemble == NVT || control->ensemble == bNVT) + Add_dBond_to_Forces( i, pj, system, data, workspace, lists ); + else + Add_dBond_to_Forces_NPT( i, pj, system, data, workspace, lists ); + } } void Validate_Lists( static_storage *workspace, list **lists, int step, int n, - int Hmax, int Htop, int num_bonds, int num_hbonds ) + int Hmax, int Htop, int num_bonds, int num_hbonds ) { - int i, flag; - list *bonds, *hbonds; - - bonds = *lists + BONDS; - hbonds = *lists + HBONDS; - - /* far neighbors */ - if( Htop > Hmax * DANGER_ZONE ) { - workspace->realloc.Htop = Htop; - if( Htop > Hmax ) { - fprintf( stderr, - "step%d - ran out of space on H matrix: Htop=%d, max = %d", - step, Htop, Hmax ); - exit(INSUFFICIENT_SPACE); + int i, flag; + list *bonds, *hbonds; + + bonds = *lists + BONDS; + hbonds = *lists + HBONDS; + + /* far neighbors */ + if ( Htop > Hmax * DANGER_ZONE ) + { + workspace->realloc.Htop = Htop; + if ( Htop > Hmax ) + { + fprintf( stderr, + "step%d - ran out of space on H matrix: Htop=%d, max = %d", + step, Htop, Hmax ); + exit(INSUFFICIENT_SPACE); + } } - } - - /* bond list */ - flag = -1; - workspace->realloc.num_bonds = num_bonds; - for( i = 0; i < n-1; ++i ) - if( End_Index(i, bonds) >= Start_Index(i+1, bonds)-2 ) { - workspace->realloc.bonds = 1; - if( End_Index(i, bonds) > Start_Index(i+1, bonds) ) - flag = i; - } - - if( flag > -1 ) { - fprintf( stderr, "step%d-bondchk failed: i=%d end(i)=%d str(i+1)=%d\n", - step, flag, End_Index(flag,bonds), Start_Index(flag+1,bonds) ); - exit(INSUFFICIENT_SPACE); - } - - if( End_Index(i, bonds) >= bonds->num_intrs-2 ) { - workspace->realloc.bonds = 1; - - if( End_Index(i, bonds) > bonds->num_intrs ) { - fprintf( stderr, "step%d-bondchk failed: i=%d end(i)=%d bond_end=%d\n", - step, flag, End_Index(i,bonds), bonds->num_intrs ); - exit(INSUFFICIENT_SPACE); - } - } - - - /* hbonds list */ - if( workspace->num_H > 0 ) { + + /* bond list */ flag = -1; - workspace->realloc.num_hbonds = num_hbonds; - for( i = 0; i < workspace->num_H-1; ++i ) - if( Num_Entries(i, hbonds) >= - (Start_Index(i+1, hbonds) - Start_Index(i, hbonds)) * DANGER_ZONE ) { - workspace->realloc.hbonds = 1; - if( End_Index(i, hbonds) > Start_Index(i+1, hbonds) ) - flag = i; - } - - if( flag > -1 ) { - fprintf( stderr, "step%d-hbondchk failed: i=%d end(i)=%d str(i+1)=%d\n", - step, flag, End_Index(flag,hbonds), Start_Index(flag+1,hbonds) ); - exit(INSUFFICIENT_SPACE); + workspace->realloc.num_bonds = num_bonds; + for ( i = 0; i < n - 1; ++i ) + if ( End_Index(i, bonds) >= Start_Index(i + 1, bonds) - 2 ) + { + workspace->realloc.bonds = 1; + if ( End_Index(i, bonds) > Start_Index(i + 1, bonds) ) + flag = i; + } + + if ( flag > -1 ) + { + fprintf( stderr, "step%d-bondchk failed: i=%d end(i)=%d str(i+1)=%d\n", + step, flag, End_Index(flag, bonds), Start_Index(flag + 1, bonds) ); + exit(INSUFFICIENT_SPACE); + } + + if ( End_Index(i, bonds) >= bonds->num_intrs - 2 ) + { + workspace->realloc.bonds = 1; + + if ( End_Index(i, bonds) > bonds->num_intrs ) + { + fprintf( stderr, "step%d-bondchk failed: i=%d end(i)=%d bond_end=%d\n", + step, flag, End_Index(i, bonds), bonds->num_intrs ); + exit(INSUFFICIENT_SPACE); + } } - if( Num_Entries(i,hbonds) >= - (hbonds->num_intrs - Start_Index(i,hbonds)) * DANGER_ZONE ) { - workspace->realloc.hbonds = 1; - if( End_Index(i, hbonds) > hbonds->num_intrs ) { - fprintf( stderr, "step%d-hbondchk failed: i=%d end(i)=%d hbondend=%d\n", - step, flag, End_Index(i,hbonds), hbonds->num_intrs ); - exit(INSUFFICIENT_SPACE); - } + /* hbonds list */ + if ( workspace->num_H > 0 ) + { + flag = -1; + workspace->realloc.num_hbonds = num_hbonds; + for ( i = 0; i < workspace->num_H - 1; ++i ) + if ( Num_Entries(i, hbonds) >= + (Start_Index(i + 1, hbonds) - Start_Index(i, hbonds)) * DANGER_ZONE ) + { + workspace->realloc.hbonds = 1; + if ( End_Index(i, hbonds) > Start_Index(i + 1, hbonds) ) + flag = i; + } + + if ( flag > -1 ) + { + fprintf( stderr, "step%d-hbondchk failed: i=%d end(i)=%d str(i+1)=%d\n", + step, flag, End_Index(flag, hbonds), Start_Index(flag + 1, hbonds) ); + exit(INSUFFICIENT_SPACE); + } + + if ( Num_Entries(i, hbonds) >= + (hbonds->num_intrs - Start_Index(i, hbonds)) * DANGER_ZONE ) + { + workspace->realloc.hbonds = 1; + + if ( End_Index(i, hbonds) > hbonds->num_intrs ) + { + fprintf( stderr, "step%d-hbondchk failed: i=%d end(i)=%d hbondend=%d\n", + step, flag, End_Index(i, hbonds), hbonds->num_intrs ); + exit(INSUFFICIENT_SPACE); + } + } } - } } -void Init_Forces( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) { - int i, j, pj; - int start_i, end_i; - int type_i, type_j; - int Htop, btop_i, btop_j, num_bonds, num_hbonds; - int ihb, jhb, ihb_top, jhb_top; - int flag; - real r_ij, r2, self_coef; - real dr3gamij_1, dr3gamij_3, Tap; - //real val, dif, base; - real C12, C34, C56; - real Cln_BOp_s, Cln_BOp_pi, Cln_BOp_pi2; - real BO, BO_s, BO_pi, BO_pi2; - real p_boc1, p_boc2; - sparse_matrix *H; - list *far_nbrs, *bonds, *hbonds; - single_body_parameters *sbp_i, *sbp_j; - two_body_parameters *twbp; - far_neighbor_data *nbr_pj; - //LR_lookup_table *t; - reax_atom *atom_i, *atom_j; - bond_data *ibond, *jbond; - bond_order_data *bo_ij, *bo_ji; - - far_nbrs = *lists + FAR_NBRS; - bonds = *lists + BONDS; - hbonds = *lists + HBONDS; - - H = workspace->H; - Htop = 0; - num_bonds = 0; - num_hbonds = 0; - btop_i = btop_j = 0; - p_boc1 = system->reaxprm.gp.l[0]; - p_boc2 = system->reaxprm.gp.l[1]; - - for( i = 0; i < system->N; ++i ) { - atom_i = &(system->atoms[i]); - type_i = atom_i->type; - start_i = Start_Index(i, far_nbrs); - end_i = End_Index(i, far_nbrs); - H->start[i] = Htop; - btop_i = End_Index( i, bonds ); - sbp_i = &(system->reaxprm.sbp[type_i]); - ihb = ihb_top = -1; - if( control->hb_cut > 0 && (ihb=sbp_i->p_hbond) == 1 ) - ihb_top = End_Index( workspace->hbond_index[i], hbonds ); - - for( pj = start_i; pj < end_i; ++pj ) { - nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); - j = nbr_pj->nbr; - atom_j = &(system->atoms[j]); - - flag = 0; - if((data->step-data->prev_steps) % control->reneighbor == 0) { - if( nbr_pj->d <= control->r_cut) - flag = 1; - else flag = 0; - } - else if((nbr_pj->d=Sq_Distance_on_T3(atom_i->x,atom_j->x,&(system->box), - nbr_pj->dvec))<=SQR(control->r_cut)){ - nbr_pj->d = sqrt(nbr_pj->d); - flag = 1; - } - - if( flag ){ - type_j = system->atoms[j].type; - r_ij = nbr_pj->d; - sbp_j = &(system->reaxprm.sbp[type_j]); - twbp = &(system->reaxprm.tbp[type_i][type_j]); - self_coef = (i == j) ? 0.5 : 1.0; - - /* H matrix entry */ - Tap = control->Tap7 * r_ij + control->Tap6; - Tap = Tap * r_ij + control->Tap5; - Tap = Tap * r_ij + control->Tap4; - Tap = Tap * r_ij + control->Tap3; - Tap = Tap * r_ij + control->Tap2; - Tap = Tap * r_ij + control->Tap1; - Tap = Tap * r_ij + control->Tap0; - - dr3gamij_1 = ( r_ij * r_ij * r_ij + twbp->gamma ); - dr3gamij_3 = POW( dr3gamij_1 , 0.33333333333333 ); - - H->entries[Htop].j = j; - H->entries[Htop].val = self_coef * Tap * EV_to_KCALpMOL / dr3gamij_3; - ++Htop; - - /* hydrogen bond lists */ - if( control->hb_cut > 0 && (ihb==1 || ihb==2) && - nbr_pj->d <= control->hb_cut ) { - // fprintf( stderr, "%d %d\n", atom1, atom2 ); - jhb = sbp_j->p_hbond; - if( ihb == 1 && jhb == 2 ) { - hbonds->select.hbond_list[ihb_top].nbr = j; - hbonds->select.hbond_list[ihb_top].scl = 1; - hbonds->select.hbond_list[ihb_top].ptr = nbr_pj; - ++ihb_top; - ++num_hbonds; - } - else if( ihb == 2 && jhb == 1 ) { - jhb_top = End_Index( workspace->hbond_index[j], hbonds ); - hbonds->select.hbond_list[jhb_top].nbr = i; - hbonds->select.hbond_list[jhb_top].scl = -1; - hbonds->select.hbond_list[jhb_top].ptr = nbr_pj; - Set_End_Index( workspace->hbond_index[j], jhb_top+1, hbonds ); - ++num_hbonds; - } - } - - /* uncorrected bond orders */ - if( far_nbrs->select.far_nbr_list[pj].d <= control->nbr_cut ) { - r2 = SQR(r_ij); - - if( sbp_i->r_s > 0.0 && sbp_j->r_s > 0.0) { - C12 = twbp->p_bo1 * POW( r_ij / twbp->r_s, twbp->p_bo2 ); - BO_s = (1.0 + control->bo_cut) * EXP( C12 ); - } - else BO_s = C12 = 0.0; - - if( sbp_i->r_pi > 0.0 && sbp_j->r_pi > 0.0) { - C34 = twbp->p_bo3 * POW( r_ij / twbp->r_p, twbp->p_bo4 ); - BO_pi = EXP( C34 ); - } - else BO_pi = C34 = 0.0; - - if( sbp_i->r_pi_pi > 0.0 && sbp_j->r_pi_pi > 0.0) { - C56 = twbp->p_bo5 * POW( r_ij / twbp->r_pp, twbp->p_bo6 ); - BO_pi2= EXP( C56 ); - } - else BO_pi2 = C56 = 0.0; - - /* Initially BO values are the uncorrected ones, page 1 */ - BO = BO_s + BO_pi + BO_pi2; - - if( BO >= control->bo_cut ) { - num_bonds += 2; - /****** bonds i-j and j-i ******/ - ibond = &( bonds->select.bond_list[btop_i] ); - btop_j = End_Index( j, bonds ); - jbond = &(bonds->select.bond_list[btop_j]); - - ibond->nbr = j; - jbond->nbr = i; - ibond->d = r_ij; - jbond->d = r_ij; - rvec_Copy( ibond->dvec, nbr_pj->dvec ); - rvec_Scale( jbond->dvec, -1, nbr_pj->dvec ); - ivec_Copy( ibond->rel_box, nbr_pj->rel_box ); - ivec_Scale( jbond->rel_box, -1, nbr_pj->rel_box ); - ibond->dbond_index = btop_i; - jbond->dbond_index = btop_i; - ibond->sym_index = btop_j; - jbond->sym_index = btop_i; - ++btop_i; - Set_End_Index( j, btop_j+1, bonds ); - - bo_ij = &( ibond->bo_data ); - bo_ji = &( jbond->bo_data ); - bo_ji->BO = bo_ij->BO = BO; - bo_ji->BO_s = bo_ij->BO_s = BO_s; - bo_ji->BO_pi = bo_ij->BO_pi = BO_pi; - bo_ji->BO_pi2 = bo_ij->BO_pi2 = BO_pi2; - - /* Bond Order page2-3, derivative of total bond order prime */ - Cln_BOp_s = twbp->p_bo2 * C12 / r2; - Cln_BOp_pi = twbp->p_bo4 * C34 / r2; - Cln_BOp_pi2 = twbp->p_bo6 * C56 / r2; - - /* Only dln_BOp_xx wrt. dr_i is stored here, note that - dln_BOp_xx/dr_i = -dln_BOp_xx/dr_j and all others are 0 */ - rvec_Scale(bo_ij->dln_BOp_s,-bo_ij->BO_s*Cln_BOp_s,ibond->dvec); - rvec_Scale(bo_ij->dln_BOp_pi,-bo_ij->BO_pi*Cln_BOp_pi,ibond->dvec); - rvec_Scale(bo_ij->dln_BOp_pi2, - -bo_ij->BO_pi2*Cln_BOp_pi2,ibond->dvec); - rvec_Scale(bo_ji->dln_BOp_s, -1., bo_ij->dln_BOp_s); - rvec_Scale(bo_ji->dln_BOp_pi, -1., bo_ij->dln_BOp_pi ); - rvec_Scale(bo_ji->dln_BOp_pi2, -1., bo_ij->dln_BOp_pi2 ); - - /* Only dBOp wrt. dr_i is stored here, note that - dBOp/dr_i = -dBOp/dr_j and all others are 0 */ - rvec_Scale( bo_ij->dBOp, - -(bo_ij->BO_s * Cln_BOp_s + - bo_ij->BO_pi * Cln_BOp_pi + - bo_ij->BO_pi2 * Cln_BOp_pi2), ibond->dvec ); - rvec_Scale( bo_ji->dBOp, -1., bo_ij->dBOp ); - - rvec_Add( workspace->dDeltap_self[i], bo_ij->dBOp ); - rvec_Add( workspace->dDeltap_self[j], bo_ji->dBOp ); - - bo_ij->BO_s -= control->bo_cut; - bo_ij->BO -= control->bo_cut; - bo_ji->BO_s -= control->bo_cut; - bo_ji->BO -= control->bo_cut; - workspace->total_bond_order[i] += bo_ij->BO; //currently total_BOp - workspace->total_bond_order[j] += bo_ji->BO; //currently total_BOp - bo_ij->Cdbo = bo_ij->Cdbopi = bo_ij->Cdbopi2 = 0.0; - bo_ji->Cdbo = bo_ji->Cdbopi = bo_ji->Cdbopi2 = 0.0; - - /*fprintf( stderr, "%d %d %g %g %g\n", - i+1, j+1, bo_ij->BO, bo_ij->BO_pi, bo_ij->BO_pi2 );*/ - - /*fprintf( stderr, "Cln_BOp_s: %f, pbo2: %f, C12:%f\n", - Cln_BOp_s, twbp->p_bo2, C12 ); - fprintf( stderr, "Cln_BOp_pi: %f, pbo4: %f, C34:%f\n", - Cln_BOp_pi, twbp->p_bo4, C34 ); - fprintf( stderr, "Cln_BOp_pi2: %f, pbo6: %f, C56:%f\n", - Cln_BOp_pi2, twbp->p_bo6, C56 );*/ - /*fprintf(stderr, "pbo1: %f, pbo2:%f\n", twbp->p_bo1, twbp->p_bo2); - fprintf(stderr, "pbo3: %f, pbo4:%f\n", twbp->p_bo3, twbp->p_bo4); - fprintf(stderr, "pbo5: %f, pbo6:%f\n", twbp->p_bo5, twbp->p_bo6); - fprintf( stderr, "r_s: %f, r_p: %f, r_pp: %f\n", - twbp->r_s, twbp->r_p, twbp->r_pp ); - fprintf( stderr, "C12: %g, C34:%g, C56:%g\n", C12, C34, C56 );*/ - - /*fprintf( stderr, "\tfactors: %g %g %g\n", - -(bo_ij->BO_s * Cln_BOp_s + bo_ij->BO_pi * Cln_BOp_pi + - bo_ij->BO_pi2 * Cln_BOp_pp), - -bo_ij->BO_pi * Cln_BOp_pi, -bo_ij->BO_pi2 * Cln_BOp_pi2 );*/ - /*fprintf( stderr, "dBOpi:\t[%g, %g, %g]\n", - bo_ij->dBOp[0], bo_ij->dBOp[1], bo_ij->dBOp[2] ); - fprintf( stderr, "dBOpi:\t[%g, %g, %g]\n", - bo_ij->dln_BOp_pi[0], bo_ij->dln_BOp_pi[1], - bo_ij->dln_BOp_pi[2] ); - fprintf( stderr, "dBOpi2:\t[%g, %g, %g]\n\n", - bo_ij->dln_BOp_pi2[0], bo_ij->dln_BOp_pi2[1], - bo_ij->dln_BOp_pi2[2] );*/ - - Set_End_Index( j, btop_j+1, bonds ); - } - } - } +void Init_Forces( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) +{ + int i, j, pj; + int start_i, end_i; + int type_i, type_j; + int Htop, btop_i, btop_j, num_bonds, num_hbonds; + int ihb, jhb, ihb_top, jhb_top; + int flag; + real r_ij, r2, self_coef; + real dr3gamij_1, dr3gamij_3, Tap; + //real val, dif, base; + real C12, C34, C56; + real Cln_BOp_s, Cln_BOp_pi, Cln_BOp_pi2; + real BO, BO_s, BO_pi, BO_pi2; + real p_boc1, p_boc2; + sparse_matrix *H; + list *far_nbrs, *bonds, *hbonds; + single_body_parameters *sbp_i, *sbp_j; + two_body_parameters *twbp; + far_neighbor_data *nbr_pj; + //LR_lookup_table *t; + reax_atom *atom_i, *atom_j; + bond_data *ibond, *jbond; + bond_order_data *bo_ij, *bo_ji; + + far_nbrs = *lists + FAR_NBRS; + bonds = *lists + BONDS; + hbonds = *lists + HBONDS; + + H = workspace->H; + Htop = 0; + num_bonds = 0; + num_hbonds = 0; + btop_i = btop_j = 0; + p_boc1 = system->reaxprm.gp.l[0]; + p_boc2 = system->reaxprm.gp.l[1]; + + for ( i = 0; i < system->N; ++i ) + { + atom_i = &(system->atoms[i]); + type_i = atom_i->type; + start_i = Start_Index(i, far_nbrs); + end_i = End_Index(i, far_nbrs); + H->start[i] = Htop; + btop_i = End_Index( i, bonds ); + sbp_i = &(system->reaxprm.sbp[type_i]); + ihb = ihb_top = -1; + if ( control->hb_cut > 0 && (ihb = sbp_i->p_hbond) == 1 ) + ihb_top = End_Index( workspace->hbond_index[i], hbonds ); + + for ( pj = start_i; pj < end_i; ++pj ) + { + nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); + j = nbr_pj->nbr; + atom_j = &(system->atoms[j]); + + flag = 0; + if ((data->step - data->prev_steps) % control->reneighbor == 0) + { + if ( nbr_pj->d <= control->r_cut) + flag = 1; + else flag = 0; + } + else if ((nbr_pj->d = Sq_Distance_on_T3(atom_i->x, atom_j->x, &(system->box), + nbr_pj->dvec)) <= SQR(control->r_cut)) + { + nbr_pj->d = sqrt(nbr_pj->d); + flag = 1; + } + + if ( flag ) + { + type_j = system->atoms[j].type; + r_ij = nbr_pj->d; + sbp_j = &(system->reaxprm.sbp[type_j]); + twbp = &(system->reaxprm.tbp[type_i][type_j]); + self_coef = (i == j) ? 0.5 : 1.0; + + /* H matrix entry */ + Tap = control->Tap7 * r_ij + control->Tap6; + Tap = Tap * r_ij + control->Tap5; + Tap = Tap * r_ij + control->Tap4; + Tap = Tap * r_ij + control->Tap3; + Tap = Tap * r_ij + control->Tap2; + Tap = Tap * r_ij + control->Tap1; + Tap = Tap * r_ij + control->Tap0; + + dr3gamij_1 = ( r_ij * r_ij * r_ij + twbp->gamma ); + dr3gamij_3 = POW( dr3gamij_1 , 0.33333333333333 ); + + H->entries[Htop].j = j; + H->entries[Htop].val = self_coef * Tap * EV_to_KCALpMOL / dr3gamij_3; + ++Htop; + + /* hydrogen bond lists */ + if ( control->hb_cut > 0 && (ihb == 1 || ihb == 2) && + nbr_pj->d <= control->hb_cut ) + { + // fprintf( stderr, "%d %d\n", atom1, atom2 ); + jhb = sbp_j->p_hbond; + if ( ihb == 1 && jhb == 2 ) + { + hbonds->select.hbond_list[ihb_top].nbr = j; + hbonds->select.hbond_list[ihb_top].scl = 1; + hbonds->select.hbond_list[ihb_top].ptr = nbr_pj; + ++ihb_top; + ++num_hbonds; + } + else if ( ihb == 2 && jhb == 1 ) + { + jhb_top = End_Index( workspace->hbond_index[j], hbonds ); + hbonds->select.hbond_list[jhb_top].nbr = i; + hbonds->select.hbond_list[jhb_top].scl = -1; + hbonds->select.hbond_list[jhb_top].ptr = nbr_pj; + Set_End_Index( workspace->hbond_index[j], jhb_top + 1, hbonds ); + ++num_hbonds; + } + } + + /* uncorrected bond orders */ + if ( far_nbrs->select.far_nbr_list[pj].d <= control->nbr_cut ) + { + r2 = SQR(r_ij); + + if ( sbp_i->r_s > 0.0 && sbp_j->r_s > 0.0) + { + C12 = twbp->p_bo1 * POW( r_ij / twbp->r_s, twbp->p_bo2 ); + BO_s = (1.0 + control->bo_cut) * EXP( C12 ); + } + else BO_s = C12 = 0.0; + + if ( sbp_i->r_pi > 0.0 && sbp_j->r_pi > 0.0) + { + C34 = twbp->p_bo3 * POW( r_ij / twbp->r_p, twbp->p_bo4 ); + BO_pi = EXP( C34 ); + } + else BO_pi = C34 = 0.0; + + if ( sbp_i->r_pi_pi > 0.0 && sbp_j->r_pi_pi > 0.0) + { + C56 = twbp->p_bo5 * POW( r_ij / twbp->r_pp, twbp->p_bo6 ); + BO_pi2 = EXP( C56 ); + } + else BO_pi2 = C56 = 0.0; + + /* Initially BO values are the uncorrected ones, page 1 */ + BO = BO_s + BO_pi + BO_pi2; + + if ( BO >= control->bo_cut ) + { + num_bonds += 2; + /****** bonds i-j and j-i ******/ + ibond = &( bonds->select.bond_list[btop_i] ); + btop_j = End_Index( j, bonds ); + jbond = &(bonds->select.bond_list[btop_j]); + + ibond->nbr = j; + jbond->nbr = i; + ibond->d = r_ij; + jbond->d = r_ij; + rvec_Copy( ibond->dvec, nbr_pj->dvec ); + rvec_Scale( jbond->dvec, -1, nbr_pj->dvec ); + ivec_Copy( ibond->rel_box, nbr_pj->rel_box ); + ivec_Scale( jbond->rel_box, -1, nbr_pj->rel_box ); + ibond->dbond_index = btop_i; + jbond->dbond_index = btop_i; + ibond->sym_index = btop_j; + jbond->sym_index = btop_i; + ++btop_i; + Set_End_Index( j, btop_j + 1, bonds ); + + bo_ij = &( ibond->bo_data ); + bo_ji = &( jbond->bo_data ); + bo_ji->BO = bo_ij->BO = BO; + bo_ji->BO_s = bo_ij->BO_s = BO_s; + bo_ji->BO_pi = bo_ij->BO_pi = BO_pi; + bo_ji->BO_pi2 = bo_ij->BO_pi2 = BO_pi2; + + /* Bond Order page2-3, derivative of total bond order prime */ + Cln_BOp_s = twbp->p_bo2 * C12 / r2; + Cln_BOp_pi = twbp->p_bo4 * C34 / r2; + Cln_BOp_pi2 = twbp->p_bo6 * C56 / r2; + + /* Only dln_BOp_xx wrt. dr_i is stored here, note that + dln_BOp_xx/dr_i = -dln_BOp_xx/dr_j and all others are 0 */ + rvec_Scale(bo_ij->dln_BOp_s, -bo_ij->BO_s * Cln_BOp_s, ibond->dvec); + rvec_Scale(bo_ij->dln_BOp_pi, -bo_ij->BO_pi * Cln_BOp_pi, ibond->dvec); + rvec_Scale(bo_ij->dln_BOp_pi2, + -bo_ij->BO_pi2 * Cln_BOp_pi2, ibond->dvec); + rvec_Scale(bo_ji->dln_BOp_s, -1., bo_ij->dln_BOp_s); + rvec_Scale(bo_ji->dln_BOp_pi, -1., bo_ij->dln_BOp_pi ); + rvec_Scale(bo_ji->dln_BOp_pi2, -1., bo_ij->dln_BOp_pi2 ); + + /* Only dBOp wrt. dr_i is stored here, note that + dBOp/dr_i = -dBOp/dr_j and all others are 0 */ + rvec_Scale( bo_ij->dBOp, + -(bo_ij->BO_s * Cln_BOp_s + + bo_ij->BO_pi * Cln_BOp_pi + + bo_ij->BO_pi2 * Cln_BOp_pi2), ibond->dvec ); + rvec_Scale( bo_ji->dBOp, -1., bo_ij->dBOp ); + + rvec_Add( workspace->dDeltap_self[i], bo_ij->dBOp ); + rvec_Add( workspace->dDeltap_self[j], bo_ji->dBOp ); + + bo_ij->BO_s -= control->bo_cut; + bo_ij->BO -= control->bo_cut; + bo_ji->BO_s -= control->bo_cut; + bo_ji->BO -= control->bo_cut; + workspace->total_bond_order[i] += bo_ij->BO; //currently total_BOp + workspace->total_bond_order[j] += bo_ji->BO; //currently total_BOp + bo_ij->Cdbo = bo_ij->Cdbopi = bo_ij->Cdbopi2 = 0.0; + bo_ji->Cdbo = bo_ji->Cdbopi = bo_ji->Cdbopi2 = 0.0; + + /*fprintf( stderr, "%d %d %g %g %g\n", + i+1, j+1, bo_ij->BO, bo_ij->BO_pi, bo_ij->BO_pi2 );*/ + + /*fprintf( stderr, "Cln_BOp_s: %f, pbo2: %f, C12:%f\n", + Cln_BOp_s, twbp->p_bo2, C12 ); + fprintf( stderr, "Cln_BOp_pi: %f, pbo4: %f, C34:%f\n", + Cln_BOp_pi, twbp->p_bo4, C34 ); + fprintf( stderr, "Cln_BOp_pi2: %f, pbo6: %f, C56:%f\n", + Cln_BOp_pi2, twbp->p_bo6, C56 );*/ + /*fprintf(stderr, "pbo1: %f, pbo2:%f\n", twbp->p_bo1, twbp->p_bo2); + fprintf(stderr, "pbo3: %f, pbo4:%f\n", twbp->p_bo3, twbp->p_bo4); + fprintf(stderr, "pbo5: %f, pbo6:%f\n", twbp->p_bo5, twbp->p_bo6); + fprintf( stderr, "r_s: %f, r_p: %f, r_pp: %f\n", + twbp->r_s, twbp->r_p, twbp->r_pp ); + fprintf( stderr, "C12: %g, C34:%g, C56:%g\n", C12, C34, C56 );*/ + + /*fprintf( stderr, "\tfactors: %g %g %g\n", + -(bo_ij->BO_s * Cln_BOp_s + bo_ij->BO_pi * Cln_BOp_pi + + bo_ij->BO_pi2 * Cln_BOp_pp), + -bo_ij->BO_pi * Cln_BOp_pi, -bo_ij->BO_pi2 * Cln_BOp_pi2 );*/ + /*fprintf( stderr, "dBOpi:\t[%g, %g, %g]\n", + bo_ij->dBOp[0], bo_ij->dBOp[1], bo_ij->dBOp[2] ); + fprintf( stderr, "dBOpi:\t[%g, %g, %g]\n", + bo_ij->dln_BOp_pi[0], bo_ij->dln_BOp_pi[1], + bo_ij->dln_BOp_pi[2] ); + fprintf( stderr, "dBOpi2:\t[%g, %g, %g]\n\n", + bo_ij->dln_BOp_pi2[0], bo_ij->dln_BOp_pi2[1], + bo_ij->dln_BOp_pi2[2] );*/ + + Set_End_Index( j, btop_j + 1, bonds ); + } + } + } + } + + H->entries[Htop].j = i; + H->entries[Htop].val = system->reaxprm.sbp[type_i].eta; + ++Htop; + + Set_End_Index( i, btop_i, bonds ); + if ( ihb == 1 ) + Set_End_Index( workspace->hbond_index[i], ihb_top, hbonds ); + //fprintf( stderr, "%d bonds start: %d, end: %d\n", + // i, Start_Index( i, bonds ), End_Index( i, bonds ) ); } - H->entries[Htop].j = i; - H->entries[Htop].val = system->reaxprm.sbp[type_i].eta; - ++Htop; - - Set_End_Index( i, btop_i, bonds ); - if( ihb == 1 ) - Set_End_Index( workspace->hbond_index[i], ihb_top, hbonds ); - //fprintf( stderr, "%d bonds start: %d, end: %d\n", - // i, Start_Index( i, bonds ), End_Index( i, bonds ) ); - } - - // mark the end of j list - H->start[i] = Htop; - /* validate lists - decide if reallocation is required! */ - Validate_Lists( workspace, lists, - data->step, system->N, H->m, Htop, num_bonds, num_hbonds ); + // mark the end of j list + H->start[i] = Htop; + /* validate lists - decide if reallocation is required! */ + Validate_Lists( workspace, lists, + data->step, system->N, H->m, Htop, num_bonds, num_hbonds ); #if defined(DEBUG_FOCUS) - fprintf( stderr, "step%d: Htop = %d, num_bonds = %d, num_hbonds = %d\n", - data->step, Htop, num_bonds, num_hbonds ); - + fprintf( stderr, "step%d: Htop = %d, num_bonds = %d, num_hbonds = %d\n", + data->step, Htop, num_bonds, num_hbonds ); + #endif } -void Init_Forces_Tab( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) { - int i, j, pj; - int start_i, end_i; - int type_i, type_j; - int Htop, btop_i, btop_j, num_bonds, num_hbonds; - int tmin, tmax, r; - int ihb, jhb, ihb_top, jhb_top; - int flag; - real r_ij, r2, self_coef; - real val, dif, base; - real C12, C34, C56; - real Cln_BOp_s, Cln_BOp_pi, Cln_BOp_pi2; - real BO, BO_s, BO_pi, BO_pi2; - real p_boc1, p_boc2; - sparse_matrix *H; - list *far_nbrs, *bonds, *hbonds; - single_body_parameters *sbp_i, *sbp_j; - two_body_parameters *twbp; - far_neighbor_data *nbr_pj; - LR_lookup_table *t; - reax_atom *atom_i, *atom_j; - bond_data *ibond, *jbond; - bond_order_data *bo_ij, *bo_ji; - - far_nbrs = *lists + FAR_NBRS; - bonds = *lists + BONDS; - hbonds = *lists + HBONDS; - - H = workspace->H; - Htop = 0; - num_bonds = 0; - num_hbonds = 0; - btop_i = btop_j = 0; - p_boc1 = system->reaxprm.gp.l[0]; - p_boc2 = system->reaxprm.gp.l[1]; - - for( i = 0; i < system->N; ++i ) { - atom_i = &(system->atoms[i]); - type_i = atom_i->type; - start_i = Start_Index(i, far_nbrs); - end_i = End_Index(i, far_nbrs); - H->start[i] = Htop; - btop_i = End_Index( i, bonds ); - sbp_i = &(system->reaxprm.sbp[type_i]); - ihb = ihb_top = -1; - if( control->hb_cut > 0 && (ihb=sbp_i->p_hbond) == 1 ) - ihb_top = End_Index( workspace->hbond_index[i], hbonds ); - - for( pj = start_i; pj < end_i; ++pj ) { - nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); - j = nbr_pj->nbr; - atom_j = &(system->atoms[j]); - - flag = 0; - if((data->step-data->prev_steps) % control->reneighbor == 0) { - if(nbr_pj->d <= control->r_cut) - flag = 1; - else flag = 0; - } - else if((nbr_pj->d=Sq_Distance_on_T3(atom_i->x,atom_j->x,&(system->box), - nbr_pj->dvec))<=SQR(control->r_cut)){ - nbr_pj->d = sqrt(nbr_pj->d); - flag = 1; - } - - if( flag ){ - type_j = system->atoms[j].type; - r_ij = nbr_pj->d; - sbp_j = &(system->reaxprm.sbp[type_j]); - twbp = &(system->reaxprm.tbp[type_i][type_j]); - self_coef = (i == j) ? 0.5 : 1.0; - tmin = MIN( type_i, type_j ); - tmax = MAX( type_i, type_j ); - t = &( LR[tmin][tmax] ); - - /* cubic spline interpolation */ - r = (int)(r_ij * t->inv_dx); - if( r == 0 ) ++r; - base = (real)(r+1) * t->dx; - dif = r_ij - base; - val = ((t->ele[r].d*dif + t->ele[r].c)*dif + t->ele[r].b)*dif + - t->ele[r].a; - val *= EV_to_KCALpMOL / C_ele; - - H->entries[Htop].j = j; - H->entries[Htop].val = self_coef * val; - ++Htop; - - /* hydrogen bond lists */ - if( control->hb_cut > 0 && (ihb==1 || ihb==2) && - nbr_pj->d <= control->hb_cut ) { - // fprintf( stderr, "%d %d\n", atom1, atom2 ); - jhb = sbp_j->p_hbond; - if( ihb == 1 && jhb == 2 ) { - hbonds->select.hbond_list[ihb_top].nbr = j; - hbonds->select.hbond_list[ihb_top].scl = 1; - hbonds->select.hbond_list[ihb_top].ptr = nbr_pj; - ++ihb_top; - ++num_hbonds; - } - else if( ihb == 2 && jhb == 1 ) { - jhb_top = End_Index( workspace->hbond_index[j], hbonds ); - hbonds->select.hbond_list[jhb_top].nbr = i; - hbonds->select.hbond_list[jhb_top].scl = -1; - hbonds->select.hbond_list[jhb_top].ptr = nbr_pj; - Set_End_Index( workspace->hbond_index[j], jhb_top+1, hbonds ); - ++num_hbonds; - } - } - - /* uncorrected bond orders */ - if( far_nbrs->select.far_nbr_list[pj].d <= control->nbr_cut ) { - r2 = SQR(r_ij); - - if( sbp_i->r_s > 0.0 && sbp_j->r_s > 0.0) { - C12 = twbp->p_bo1 * POW( r_ij / twbp->r_s, twbp->p_bo2 ); - BO_s = (1.0 + control->bo_cut) * EXP( C12 ); - } - else BO_s = C12 = 0.0; - - if( sbp_i->r_pi > 0.0 && sbp_j->r_pi > 0.0) { - C34 = twbp->p_bo3 * POW( r_ij / twbp->r_p, twbp->p_bo4 ); - BO_pi = EXP( C34 ); - } - else BO_pi = C34 = 0.0; - - if( sbp_i->r_pi_pi > 0.0 && sbp_j->r_pi_pi > 0.0) { - C56 = twbp->p_bo5 * POW( r_ij / twbp->r_pp, twbp->p_bo6 ); - BO_pi2= EXP( C56 ); - } - else BO_pi2 = C56 = 0.0; - - /* Initially BO values are the uncorrected ones, page 1 */ - BO = BO_s + BO_pi + BO_pi2; - - if( BO >= control->bo_cut ) { - num_bonds += 2; - /****** bonds i-j and j-i ******/ - ibond = &( bonds->select.bond_list[btop_i] ); - btop_j = End_Index( j, bonds ); - jbond = &(bonds->select.bond_list[btop_j]); - - ibond->nbr = j; - jbond->nbr = i; - ibond->d = r_ij; - jbond->d = r_ij; - rvec_Copy( ibond->dvec, nbr_pj->dvec ); - //fprintf (stderr, " %f - %f - %f \n", nbr_pj->dvec[0], nbr_pj->dvec[1], nbr_pj->dvec[2]); - rvec_Scale( jbond->dvec, -1, nbr_pj->dvec ); - ivec_Copy( ibond->rel_box, nbr_pj->rel_box ); - ivec_Scale( jbond->rel_box, -1, nbr_pj->rel_box ); - ibond->dbond_index = btop_i; - jbond->dbond_index = btop_i; - ibond->sym_index = btop_j; - jbond->sym_index = btop_i; - ++btop_i; - Set_End_Index( j, btop_j+1, bonds ); - - bo_ij = &( ibond->bo_data ); - bo_ji = &( jbond->bo_data ); - bo_ji->BO = bo_ij->BO = BO; - bo_ji->BO_s = bo_ij->BO_s = BO_s; - bo_ji->BO_pi = bo_ij->BO_pi = BO_pi; - bo_ji->BO_pi2 = bo_ij->BO_pi2 = BO_pi2; - - /* Bond Order page2-3, derivative of total bond order prime */ - Cln_BOp_s = twbp->p_bo2 * C12 / r2; - Cln_BOp_pi = twbp->p_bo4 * C34 / r2; - Cln_BOp_pi2 = twbp->p_bo6 * C56 / r2; - - /* Only dln_BOp_xx wrt. dr_i is stored here, note that - dln_BOp_xx/dr_i = -dln_BOp_xx/dr_j and all others are 0 */ - rvec_Scale(bo_ij->dln_BOp_s,-bo_ij->BO_s*Cln_BOp_s,ibond->dvec); - rvec_Scale(bo_ij->dln_BOp_pi,-bo_ij->BO_pi*Cln_BOp_pi,ibond->dvec); - rvec_Scale(bo_ij->dln_BOp_pi2, - -bo_ij->BO_pi2*Cln_BOp_pi2,ibond->dvec); - rvec_Scale(bo_ji->dln_BOp_s, -1., bo_ij->dln_BOp_s); - rvec_Scale(bo_ji->dln_BOp_pi, -1., bo_ij->dln_BOp_pi ); - rvec_Scale(bo_ji->dln_BOp_pi2, -1., bo_ij->dln_BOp_pi2 ); - - /* Only dBOp wrt. dr_i is stored here, note that - dBOp/dr_i = -dBOp/dr_j and all others are 0 */ - rvec_Scale( bo_ij->dBOp, - -(bo_ij->BO_s * Cln_BOp_s + - bo_ij->BO_pi * Cln_BOp_pi + - bo_ij->BO_pi2 * Cln_BOp_pi2), ibond->dvec ); - rvec_Scale( bo_ji->dBOp, -1., bo_ij->dBOp ); - - rvec_Add( workspace->dDeltap_self[i], bo_ij->dBOp ); - rvec_Add( workspace->dDeltap_self[j], bo_ji->dBOp ); - - bo_ij->BO_s -= control->bo_cut; - bo_ij->BO -= control->bo_cut; - bo_ji->BO_s -= control->bo_cut; - bo_ji->BO -= control->bo_cut; - workspace->total_bond_order[i] += bo_ij->BO; //currently total_BOp - workspace->total_bond_order[j] += bo_ji->BO; //currently total_BOp - bo_ij->Cdbo = bo_ij->Cdbopi = bo_ij->Cdbopi2 = 0.0; - bo_ji->Cdbo = bo_ji->Cdbopi = bo_ji->Cdbopi2 = 0.0; - - Set_End_Index( j, btop_j+1, bonds ); - } - } - } +void Init_Forces_Tab( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) +{ + int i, j, pj; + int start_i, end_i; + int type_i, type_j; + int Htop, btop_i, btop_j, num_bonds, num_hbonds; + int tmin, tmax, r; + int ihb, jhb, ihb_top, jhb_top; + int flag; + real r_ij, r2, self_coef; + real val, dif, base; + real C12, C34, C56; + real Cln_BOp_s, Cln_BOp_pi, Cln_BOp_pi2; + real BO, BO_s, BO_pi, BO_pi2; + real p_boc1, p_boc2; + sparse_matrix *H; + list *far_nbrs, *bonds, *hbonds; + single_body_parameters *sbp_i, *sbp_j; + two_body_parameters *twbp; + far_neighbor_data *nbr_pj; + LR_lookup_table *t; + reax_atom *atom_i, *atom_j; + bond_data *ibond, *jbond; + bond_order_data *bo_ij, *bo_ji; + + far_nbrs = *lists + FAR_NBRS; + bonds = *lists + BONDS; + hbonds = *lists + HBONDS; + + H = workspace->H; + Htop = 0; + num_bonds = 0; + num_hbonds = 0; + btop_i = btop_j = 0; + p_boc1 = system->reaxprm.gp.l[0]; + p_boc2 = system->reaxprm.gp.l[1]; + + for ( i = 0; i < system->N; ++i ) + { + atom_i = &(system->atoms[i]); + type_i = atom_i->type; + start_i = Start_Index(i, far_nbrs); + end_i = End_Index(i, far_nbrs); + H->start[i] = Htop; + btop_i = End_Index( i, bonds ); + sbp_i = &(system->reaxprm.sbp[type_i]); + ihb = ihb_top = -1; + if ( control->hb_cut > 0 && (ihb = sbp_i->p_hbond) == 1 ) + ihb_top = End_Index( workspace->hbond_index[i], hbonds ); + + for ( pj = start_i; pj < end_i; ++pj ) + { + nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); + j = nbr_pj->nbr; + atom_j = &(system->atoms[j]); + + flag = 0; + if ((data->step - data->prev_steps) % control->reneighbor == 0) + { + if (nbr_pj->d <= control->r_cut) + flag = 1; + else flag = 0; + } + else if ((nbr_pj->d = Sq_Distance_on_T3(atom_i->x, atom_j->x, &(system->box), + nbr_pj->dvec)) <= SQR(control->r_cut)) + { + nbr_pj->d = sqrt(nbr_pj->d); + flag = 1; + } + + if ( flag ) + { + type_j = system->atoms[j].type; + r_ij = nbr_pj->d; + sbp_j = &(system->reaxprm.sbp[type_j]); + twbp = &(system->reaxprm.tbp[type_i][type_j]); + self_coef = (i == j) ? 0.5 : 1.0; + tmin = MIN( type_i, type_j ); + tmax = MAX( type_i, type_j ); + t = &( LR[tmin][tmax] ); + + /* cubic spline interpolation */ + r = (int)(r_ij * t->inv_dx); + if ( r == 0 ) ++r; + base = (real)(r + 1) * t->dx; + dif = r_ij - base; + val = ((t->ele[r].d * dif + t->ele[r].c) * dif + t->ele[r].b) * dif + + t->ele[r].a; + val *= EV_to_KCALpMOL / C_ele; + + H->entries[Htop].j = j; + H->entries[Htop].val = self_coef * val; + ++Htop; + + /* hydrogen bond lists */ + if ( control->hb_cut > 0 && (ihb == 1 || ihb == 2) && + nbr_pj->d <= control->hb_cut ) + { + // fprintf( stderr, "%d %d\n", atom1, atom2 ); + jhb = sbp_j->p_hbond; + if ( ihb == 1 && jhb == 2 ) + { + hbonds->select.hbond_list[ihb_top].nbr = j; + hbonds->select.hbond_list[ihb_top].scl = 1; + hbonds->select.hbond_list[ihb_top].ptr = nbr_pj; + ++ihb_top; + ++num_hbonds; + } + else if ( ihb == 2 && jhb == 1 ) + { + jhb_top = End_Index( workspace->hbond_index[j], hbonds ); + hbonds->select.hbond_list[jhb_top].nbr = i; + hbonds->select.hbond_list[jhb_top].scl = -1; + hbonds->select.hbond_list[jhb_top].ptr = nbr_pj; + Set_End_Index( workspace->hbond_index[j], jhb_top + 1, hbonds ); + ++num_hbonds; + } + } + + /* uncorrected bond orders */ + if ( far_nbrs->select.far_nbr_list[pj].d <= control->nbr_cut ) + { + r2 = SQR(r_ij); + + if ( sbp_i->r_s > 0.0 && sbp_j->r_s > 0.0) + { + C12 = twbp->p_bo1 * POW( r_ij / twbp->r_s, twbp->p_bo2 ); + BO_s = (1.0 + control->bo_cut) * EXP( C12 ); + } + else BO_s = C12 = 0.0; + + if ( sbp_i->r_pi > 0.0 && sbp_j->r_pi > 0.0) + { + C34 = twbp->p_bo3 * POW( r_ij / twbp->r_p, twbp->p_bo4 ); + BO_pi = EXP( C34 ); + } + else BO_pi = C34 = 0.0; + + if ( sbp_i->r_pi_pi > 0.0 && sbp_j->r_pi_pi > 0.0) + { + C56 = twbp->p_bo5 * POW( r_ij / twbp->r_pp, twbp->p_bo6 ); + BO_pi2 = EXP( C56 ); + } + else BO_pi2 = C56 = 0.0; + + /* Initially BO values are the uncorrected ones, page 1 */ + BO = BO_s + BO_pi + BO_pi2; + + if ( BO >= control->bo_cut ) + { + num_bonds += 2; + /****** bonds i-j and j-i ******/ + ibond = &( bonds->select.bond_list[btop_i] ); + btop_j = End_Index( j, bonds ); + jbond = &(bonds->select.bond_list[btop_j]); + + ibond->nbr = j; + jbond->nbr = i; + ibond->d = r_ij; + jbond->d = r_ij; + rvec_Copy( ibond->dvec, nbr_pj->dvec ); + //fprintf (stderr, " %f - %f - %f \n", nbr_pj->dvec[0], nbr_pj->dvec[1], nbr_pj->dvec[2]); + rvec_Scale( jbond->dvec, -1, nbr_pj->dvec ); + ivec_Copy( ibond->rel_box, nbr_pj->rel_box ); + ivec_Scale( jbond->rel_box, -1, nbr_pj->rel_box ); + ibond->dbond_index = btop_i; + jbond->dbond_index = btop_i; + ibond->sym_index = btop_j; + jbond->sym_index = btop_i; + ++btop_i; + Set_End_Index( j, btop_j + 1, bonds ); + + bo_ij = &( ibond->bo_data ); + bo_ji = &( jbond->bo_data ); + bo_ji->BO = bo_ij->BO = BO; + bo_ji->BO_s = bo_ij->BO_s = BO_s; + bo_ji->BO_pi = bo_ij->BO_pi = BO_pi; + bo_ji->BO_pi2 = bo_ij->BO_pi2 = BO_pi2; + + /* Bond Order page2-3, derivative of total bond order prime */ + Cln_BOp_s = twbp->p_bo2 * C12 / r2; + Cln_BOp_pi = twbp->p_bo4 * C34 / r2; + Cln_BOp_pi2 = twbp->p_bo6 * C56 / r2; + + /* Only dln_BOp_xx wrt. dr_i is stored here, note that + dln_BOp_xx/dr_i = -dln_BOp_xx/dr_j and all others are 0 */ + rvec_Scale(bo_ij->dln_BOp_s, -bo_ij->BO_s * Cln_BOp_s, ibond->dvec); + rvec_Scale(bo_ij->dln_BOp_pi, -bo_ij->BO_pi * Cln_BOp_pi, ibond->dvec); + rvec_Scale(bo_ij->dln_BOp_pi2, + -bo_ij->BO_pi2 * Cln_BOp_pi2, ibond->dvec); + rvec_Scale(bo_ji->dln_BOp_s, -1., bo_ij->dln_BOp_s); + rvec_Scale(bo_ji->dln_BOp_pi, -1., bo_ij->dln_BOp_pi ); + rvec_Scale(bo_ji->dln_BOp_pi2, -1., bo_ij->dln_BOp_pi2 ); + + /* Only dBOp wrt. dr_i is stored here, note that + dBOp/dr_i = -dBOp/dr_j and all others are 0 */ + rvec_Scale( bo_ij->dBOp, + -(bo_ij->BO_s * Cln_BOp_s + + bo_ij->BO_pi * Cln_BOp_pi + + bo_ij->BO_pi2 * Cln_BOp_pi2), ibond->dvec ); + rvec_Scale( bo_ji->dBOp, -1., bo_ij->dBOp ); + + rvec_Add( workspace->dDeltap_self[i], bo_ij->dBOp ); + rvec_Add( workspace->dDeltap_self[j], bo_ji->dBOp ); + + bo_ij->BO_s -= control->bo_cut; + bo_ij->BO -= control->bo_cut; + bo_ji->BO_s -= control->bo_cut; + bo_ji->BO -= control->bo_cut; + workspace->total_bond_order[i] += bo_ij->BO; //currently total_BOp + workspace->total_bond_order[j] += bo_ji->BO; //currently total_BOp + bo_ij->Cdbo = bo_ij->Cdbopi = bo_ij->Cdbopi2 = 0.0; + bo_ji->Cdbo = bo_ji->Cdbopi = bo_ji->Cdbopi2 = 0.0; + + Set_End_Index( j, btop_j + 1, bonds ); + } + } + } + } + + H->entries[Htop].j = i; + H->entries[Htop].val = system->reaxprm.sbp[type_i].eta; + ++Htop; + + Set_End_Index( i, btop_i, bonds ); + if ( ihb == 1 ) + Set_End_Index( workspace->hbond_index[i], ihb_top, hbonds ); } - H->entries[Htop].j = i; - H->entries[Htop].val = system->reaxprm.sbp[type_i].eta; - ++Htop; - - Set_End_Index( i, btop_i, bonds ); - if( ihb == 1 ) - Set_End_Index( workspace->hbond_index[i], ihb_top, hbonds ); - } - - // mark the end of j list - H->start[i] = Htop; - /* validate lists - decide if reallocation is required! */ - Validate_Lists( workspace, lists, - data->step, system->N, H->m, Htop, num_bonds, num_hbonds ); + // mark the end of j list + H->start[i] = Htop; + /* validate lists - decide if reallocation is required! */ + Validate_Lists( workspace, lists, + data->step, system->N, H->m, Htop, num_bonds, num_hbonds ); #if defined(DEBUG_FOCUS) - fprintf( stderr, "step%d: Htop = %d, num_bonds = %d, num_hbonds = %d\n", - data->step, Htop, num_bonds, num_hbonds ); - //Print_Bonds( system, bonds, "sbonds.out" ); - //Print_Bond_List2( system, bonds, "sbonds.out" ); - //Print_Sparse_Matrix2( H, "H.out" ); + fprintf( stderr, "step%d: Htop = %d, num_bonds = %d, num_hbonds = %d\n", + data->step, Htop, num_bonds, num_hbonds ); + //Print_Bonds( system, bonds, "sbonds.out" ); + //Print_Bond_List2( system, bonds, "sbonds.out" ); + //Print_Sparse_Matrix2( H, "H.out" ); #endif } -void Estimate_Storage_Sizes( reax_system *system, control_params *control, - list **lists, int *Htop, int *hb_top, - int *bond_top, int *num_3body ) { - int i, j, pj; - int start_i, end_i; - int type_i, type_j; - int ihb, jhb; - real r_ij, r2; - real C12, C34, C56; - real BO, BO_s, BO_pi, BO_pi2; - real p_boc1, p_boc2; - list *far_nbrs; - single_body_parameters *sbp_i, *sbp_j; - two_body_parameters *twbp; - far_neighbor_data *nbr_pj; - reax_atom *atom_i, *atom_j; - - far_nbrs = *lists + FAR_NBRS; - p_boc1 = system->reaxprm.gp.l[0]; - p_boc2 = system->reaxprm.gp.l[1]; - - for( i = 0; i < system->N; ++i ) { - atom_i = &(system->atoms[i]); - type_i = atom_i->type; - start_i = Start_Index(i, far_nbrs); - end_i = End_Index(i, far_nbrs); - sbp_i = &(system->reaxprm.sbp[type_i]); - ihb = sbp_i->p_hbond; - - for( pj = start_i; pj < end_i; ++pj ) { - nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); - j = nbr_pj->nbr; - atom_j = &(system->atoms[j]); - type_j = atom_j->type; - sbp_j = &(system->reaxprm.sbp[type_j]); - twbp = &(system->reaxprm.tbp[type_i][type_j]); - - if( nbr_pj->d <= control->r_cut ) { - ++(*Htop); - - /* hydrogen bond lists */ - if( control->hb_cut > 0.1 && (ihb==1 || ihb==2) && - nbr_pj->d <= control->hb_cut ) { - jhb = sbp_j->p_hbond; - if( ihb == 1 && jhb == 2 ) - ++hb_top[i]; - else if( ihb == 2 && jhb == 1 ) - ++hb_top[j]; - } - - /* uncorrected bond orders */ - if( nbr_pj->d <= control->nbr_cut ) { - r_ij = nbr_pj->d; - r2 = SQR(r_ij); - - if( sbp_i->r_s > 0.0 && sbp_j->r_s > 0.0) { - C12 = twbp->p_bo1 * POW( r_ij / twbp->r_s, twbp->p_bo2 ); - BO_s = (1.0 + control->bo_cut) * EXP( C12 ); - } - else BO_s = C12 = 0.0; - - if( sbp_i->r_pi > 0.0 && sbp_j->r_pi > 0.0) { - C34 = twbp->p_bo3 * POW( r_ij / twbp->r_p, twbp->p_bo4 ); - BO_pi = EXP( C34 ); - } - else BO_pi = C34 = 0.0; - - if( sbp_i->r_pi_pi > 0.0 && sbp_j->r_pi_pi > 0.0) { - C56 = twbp->p_bo5 * POW( r_ij / twbp->r_pp, twbp->p_bo6 ); - BO_pi2= EXP( C56 ); - } - else BO_pi2 = C56 = 0.0; - - /* Initially BO values are the uncorrected ones, page 1 */ - BO = BO_s + BO_pi + BO_pi2; - - if( BO >= control->bo_cut ) { - ++bond_top[i]; - ++bond_top[j]; - } - } - } +void Estimate_Storage_Sizes( reax_system *system, control_params *control, + list **lists, int *Htop, int *hb_top, + int *bond_top, int *num_3body ) +{ + int i, j, pj; + int start_i, end_i; + int type_i, type_j; + int ihb, jhb; + real r_ij, r2; + real C12, C34, C56; + real BO, BO_s, BO_pi, BO_pi2; + real p_boc1, p_boc2; + list *far_nbrs; + single_body_parameters *sbp_i, *sbp_j; + two_body_parameters *twbp; + far_neighbor_data *nbr_pj; + reax_atom *atom_i, *atom_j; + + far_nbrs = *lists + FAR_NBRS; + p_boc1 = system->reaxprm.gp.l[0]; + p_boc2 = system->reaxprm.gp.l[1]; + + for ( i = 0; i < system->N; ++i ) + { + atom_i = &(system->atoms[i]); + type_i = atom_i->type; + start_i = Start_Index(i, far_nbrs); + end_i = End_Index(i, far_nbrs); + sbp_i = &(system->reaxprm.sbp[type_i]); + ihb = sbp_i->p_hbond; + + for ( pj = start_i; pj < end_i; ++pj ) + { + nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); + j = nbr_pj->nbr; + atom_j = &(system->atoms[j]); + type_j = atom_j->type; + sbp_j = &(system->reaxprm.sbp[type_j]); + twbp = &(system->reaxprm.tbp[type_i][type_j]); + + if ( nbr_pj->d <= control->r_cut ) + { + ++(*Htop); + + /* hydrogen bond lists */ + if ( control->hb_cut > 0.1 && (ihb == 1 || ihb == 2) && + nbr_pj->d <= control->hb_cut ) + { + jhb = sbp_j->p_hbond; + if ( ihb == 1 && jhb == 2 ) + ++hb_top[i]; + else if ( ihb == 2 && jhb == 1 ) + ++hb_top[j]; + } + + /* uncorrected bond orders */ + if ( nbr_pj->d <= control->nbr_cut ) + { + r_ij = nbr_pj->d; + r2 = SQR(r_ij); + + if ( sbp_i->r_s > 0.0 && sbp_j->r_s > 0.0) + { + C12 = twbp->p_bo1 * POW( r_ij / twbp->r_s, twbp->p_bo2 ); + BO_s = (1.0 + control->bo_cut) * EXP( C12 ); + } + else BO_s = C12 = 0.0; + + if ( sbp_i->r_pi > 0.0 && sbp_j->r_pi > 0.0) + { + C34 = twbp->p_bo3 * POW( r_ij / twbp->r_p, twbp->p_bo4 ); + BO_pi = EXP( C34 ); + } + else BO_pi = C34 = 0.0; + + if ( sbp_i->r_pi_pi > 0.0 && sbp_j->r_pi_pi > 0.0) + { + C56 = twbp->p_bo5 * POW( r_ij / twbp->r_pp, twbp->p_bo6 ); + BO_pi2 = EXP( C56 ); + } + else BO_pi2 = C56 = 0.0; + + /* Initially BO values are the uncorrected ones, page 1 */ + BO = BO_s + BO_pi + BO_pi2; + + if ( BO >= control->bo_cut ) + { + ++bond_top[i]; + ++bond_top[j]; + } + } + } + } + } + + *Htop += system->N; + *Htop *= SAFE_ZONE; + for ( i = 0; i < system->N; ++i ) + { + hb_top[i] = MAX( hb_top[i] * SAFE_HBONDS, MIN_HBONDS ); + *num_3body += SQR(bond_top[i]); + bond_top[i] = MAX( bond_top[i] * 2, MIN_BONDS ); } - } - - *Htop += system->N; - *Htop *= SAFE_ZONE; - for( i = 0; i < system->N; ++i ) { - hb_top[i] = MAX( hb_top[i] * SAFE_HBONDS, MIN_HBONDS ); - *num_3body += SQR(bond_top[i]); - bond_top[i] = MAX( bond_top[i] * 2, MIN_BONDS ); - } - *num_3body *= SAFE_ZONE; + *num_3body *= SAFE_ZONE; } -void Compute_Forces( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list** lists, output_controls *out_control ) +void Compute_Forces( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list** lists, output_controls *out_control ) { - real t_start, t_elapsed; - - t_start = Get_Time( ); - if( !control->tabulate ) - Init_Forces( system, control, data, workspace, lists, out_control ); - else Init_Forces_Tab( system, control, data, workspace, lists, out_control ); - t_elapsed = Get_Timing_Info( t_start ); - data->timing.init_forces += t_elapsed; + real t_start, t_elapsed; + + t_start = Get_Time( ); + if ( !control->tabulate ) + Init_Forces( system, control, data, workspace, lists, out_control ); + else Init_Forces_Tab( system, control, data, workspace, lists, out_control ); + t_elapsed = Get_Timing_Info( t_start ); + data->timing.init_forces += t_elapsed; #if defined(DEBUG_FOCUS) - fprintf( stderr, "init_forces - "); + fprintf( stderr, "init_forces - "); #endif - t_start = Get_Time( ); - Compute_Bonded_Forces( system, control, data, workspace, lists, out_control ); - t_elapsed = Get_Timing_Info( t_start ); - data->timing.bonded += t_elapsed; -#if defined(DEBUG_FOCUS) - fprintf( stderr, "bonded_forces - "); + t_start = Get_Time( ); + Compute_Bonded_Forces( system, control, data, workspace, lists, out_control ); + t_elapsed = Get_Timing_Info( t_start ); + data->timing.bonded += t_elapsed; +#if defined(DEBUG_FOCUS) + fprintf( stderr, "bonded_forces - "); #endif - t_start = Get_Time( ); - Compute_NonBonded_Forces( system, control, data, workspace, - lists, out_control ); - t_elapsed = Get_Timing_Info( t_start ); - data->timing.nonb += t_elapsed; + t_start = Get_Time( ); + Compute_NonBonded_Forces( system, control, data, workspace, + lists, out_control ); + t_elapsed = Get_Timing_Info( t_start ); + data->timing.nonb += t_elapsed; #if defined(DEBUG_FOCUS) - fprintf( stderr, "nonbondeds - "); + fprintf( stderr, "nonbondeds - "); #endif - Compute_Total_Force( system, control, data, workspace, lists ); - //Print_Total_Force( system, control, data, workspace, lists, out_control ); + Compute_Total_Force( system, control, data, workspace, lists ); + //Print_Total_Force( system, control, data, workspace, lists, out_control ); #if defined(DEBUG_FOCUS) - fprintf( stderr, "totalforces - "); - //Print_Total_Force( system, control, data, workspace, lists, out_control ); + fprintf( stderr, "totalforces - "); + //Print_Total_Force( system, control, data, workspace, lists, out_control ); #endif #ifdef TEST_FORCES - Print_Total_Force( system, control, data, workspace, lists, out_control ); - Compare_Total_Forces( system, control, data, workspace, lists, out_control ); + Print_Total_Force( system, control, data, workspace, lists, out_control ); + Compare_Total_Forces( system, control, data, workspace, lists, out_control ); #endif -#if defined(DEBUG_FOCUS) - fprintf( stderr, "forces - "); +#if defined(DEBUG_FOCUS) + fprintf( stderr, "forces - "); #endif } diff --git a/puremd_rc_1003/sPuReMD/forces.h b/puremd_rc_1003/sPuReMD/forces.h index b34dac5f..c57aa159 100644 --- a/puremd_rc_1003/sPuReMD/forces.h +++ b/puremd_rc_1003/sPuReMD/forces.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -26,9 +26,9 @@ void Init_Bonded_Force_Functions( control_params* ); -void Compute_Forces( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); +void Compute_Forces( reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls* ); -void Estimate_Storage_Sizes( reax_system*, control_params*, list**, - int*, int*, int*, int* ); +void Estimate_Storage_Sizes( reax_system*, control_params*, list**, + int*, int*, int*, int* ); #endif diff --git a/puremd_rc_1003/sPuReMD/four_body_interactions.c b/puremd_rc_1003/sPuReMD/four_body_interactions.c index 09a0c6c0..1fc7e99c 100644 --- a/puremd_rc_1003/sPuReMD/four_body_interactions.c +++ b/puremd_rc_1003/sPuReMD/four_body_interactions.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -30,635 +30,645 @@ #define MIN_SINE 1e-10 real Calculate_Omega( rvec dvec_ij, real r_ij, rvec dvec_jk, real r_jk, - rvec dvec_kl, real r_kl, rvec dvec_li, real r_li, - three_body_interaction_data *p_ijk, - three_body_interaction_data *p_jkl, - rvec dcos_omega_di, rvec dcos_omega_dj, - rvec dcos_omega_dk, rvec dcos_omega_dl, - output_controls *out_control ) + rvec dvec_kl, real r_kl, rvec dvec_li, real r_li, + three_body_interaction_data *p_ijk, + three_body_interaction_data *p_jkl, + rvec dcos_omega_di, rvec dcos_omega_dj, + rvec dcos_omega_dk, rvec dcos_omega_dl, + output_controls *out_control ) { - real unnorm_cos_omega, unnorm_sin_omega, omega; - real sin_ijk, cos_ijk, sin_jkl, cos_jkl; - real htra, htrb, htrc, hthd, hthe, hnra, hnrc, hnhd, hnhe; - real arg, poem, tel; - rvec cross_jk_kl; - - sin_ijk = SIN( p_ijk->theta ); - cos_ijk = COS( p_ijk->theta ); - sin_jkl = SIN( p_jkl->theta ); - cos_jkl = COS( p_jkl->theta ); - - /* omega */ - unnorm_cos_omega = -rvec_Dot( dvec_ij,dvec_jk )*rvec_Dot( dvec_jk,dvec_kl ) + - SQR( r_jk ) * rvec_Dot( dvec_ij,dvec_kl ); - rvec_Cross( cross_jk_kl, dvec_jk, dvec_kl ); - unnorm_sin_omega = -r_jk * rvec_Dot( dvec_ij, cross_jk_kl ); - omega = atan2( unnorm_sin_omega, unnorm_cos_omega ); - - /* derivatives */ - /* coef for adjusments to cos_theta's */ - /* rla = r_ij, rlb = r_jk, rlc = r_kl, r4 = r_li; - coshd = cos_ijk, coshe = cos_jkl; - sinhd = sin_ijk, sinhe = sin_jkl; */ - htra = r_ij + cos_ijk * ( r_kl * cos_jkl - r_jk ); - htrb = r_jk - r_ij * cos_ijk - r_kl * cos_jkl; - htrc = r_kl + cos_jkl * ( r_ij * cos_ijk - r_jk ); - hthd = r_ij * sin_ijk * ( r_jk - r_kl * cos_jkl ); - hthe = r_kl * sin_jkl * ( r_jk - r_ij * cos_ijk ); - hnra = r_kl * sin_ijk * sin_jkl; - hnrc = r_ij * sin_ijk * sin_jkl; - hnhd = r_ij * r_kl * cos_ijk * sin_jkl; - hnhe = r_ij * r_kl * sin_ijk * cos_jkl; - - - poem = 2.0 * r_ij * r_kl * sin_ijk * sin_jkl; - if( poem < 1e-20 ) poem = 1e-20; - - tel = (SQR(r_ij) + SQR(r_jk) + SQR(r_kl) - SQR(r_li)) - - 2.0 * ( r_ij * r_jk * cos_ijk - r_ij * r_kl * cos_ijk * cos_jkl + - r_jk * r_kl * cos_jkl ); - - arg = tel / poem; - if( arg > 1.0 ) arg = 1.0; - if( arg < -1.0 ) arg = -1.0; - - - /*fprintf( out_control->etor, - "%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e\n", - htra, htrb, htrc, hthd, hthe, hnra, hnrc, hnhd, hnhe ); - fprintf( out_control->etor, "%23.15e%23.15e%23.15e\n", - dvec_ij[0]/r_ij, dvec_ij[1]/r_ij, dvec_ij[2]/r_ij ); - fprintf( out_control->etor, "%23.15e%23.15e%23.15e\n", - -dvec_jk[0]/r_jk, -dvec_jk[1]/r_jk, -dvec_jk[2]/r_jk ); - fprintf( out_control->etor, "%23.15e%23.15e%23.15e\n", - -dvec_kl[0]/r_kl, -dvec_kl[1]/r_kl, -dvec_kl[2]/r_kl ); - fprintf( out_control->etor, "%23.15e%23.15e%23.15e%23.15e\n", - r_li, dvec_li[0], dvec_li[1], dvec_li[2] ); - fprintf( out_control->etor, "%23.15e%23.15e%23.15e%23.15e\n", - r_ij, r_jk, r_kl, r_li ); - fprintf( out_control->etor, "%23.15e%23.15e%23.15e%23.15e\n", - cos_ijk, cos_jkl, sin_ijk, sin_jkl ); - fprintf( out_control->etor, "%23.15e%23.15e%23.15e\n", - poem, tel, arg );*/ - /* fprintf( out_control->etor, "%23.15e%23.15e%23.15e\n", - -p_ijk->dcos_dk[0]/sin_ijk, - -p_ijk->dcos_dk[1]/sin_ijk, - -p_ijk->dcos_dk[2]/sin_ijk ); - fprintf( out_control->etor, "%23.15e%23.15e%23.15e\n", - -p_jkl->dcos_dk[0]/sin_jkl, - -p_jkl->dcos_dk[1]/sin_jkl, - -p_jkl->dcos_dk[2]/sin_jkl );*/ - - if( sin_ijk >= 0 && sin_ijk <= MIN_SINE ) sin_ijk = MIN_SINE; - else if( sin_ijk <= 0 && sin_ijk >= -MIN_SINE ) sin_ijk = -MIN_SINE; - if( sin_jkl >= 0 && sin_jkl <= MIN_SINE ) sin_jkl = MIN_SINE; - else if( sin_jkl <= 0 && sin_jkl >= -MIN_SINE ) sin_jkl = -MIN_SINE; - - // dcos_omega_di - rvec_ScaledSum( dcos_omega_di, (htra-arg*hnra)/r_ij, dvec_ij, -1., dvec_li ); - rvec_ScaledAdd( dcos_omega_di,-(hthd - arg*hnhd)/sin_ijk, p_ijk->dcos_dk ); - rvec_Scale( dcos_omega_di, 2.0 / poem, dcos_omega_di ); - - // dcos_omega_dj - rvec_ScaledSum( dcos_omega_dj,-(htra-arg*hnra)/r_ij, dvec_ij, - -htrb / r_jk, dvec_jk ); - rvec_ScaledAdd( dcos_omega_dj,-(hthd-arg*hnhd) / sin_ijk, p_ijk->dcos_dj ); - rvec_ScaledAdd( dcos_omega_dj,-(hthe-arg*hnhe) / sin_jkl, p_jkl->dcos_di ); - rvec_Scale( dcos_omega_dj, 2.0 / poem, dcos_omega_dj ); - - // dcos_omega_dk - rvec_ScaledSum( dcos_omega_dk,-(htrc-arg*hnrc) / r_kl, dvec_kl, - htrb / r_jk, dvec_jk ); - rvec_ScaledAdd( dcos_omega_dk,-(hthd-arg*hnhd) / sin_ijk, p_ijk->dcos_di ); - rvec_ScaledAdd( dcos_omega_dk,-(hthe-arg*hnhe) / sin_jkl, p_jkl->dcos_dj ); - rvec_Scale( dcos_omega_dk, 2.0 / poem, dcos_omega_dk ); - - // dcos_omega_dl - rvec_ScaledSum( dcos_omega_dl, (htrc-arg*hnrc) / r_kl, dvec_kl, 1., dvec_li ); - rvec_ScaledAdd( dcos_omega_dl,-(hthe-arg*hnhe) / sin_jkl, p_jkl->dcos_dk ); - rvec_Scale( dcos_omega_dl, 2.0 / poem, dcos_omega_dl ); - - return omega; - //return arg; + real unnorm_cos_omega, unnorm_sin_omega, omega; + real sin_ijk, cos_ijk, sin_jkl, cos_jkl; + real htra, htrb, htrc, hthd, hthe, hnra, hnrc, hnhd, hnhe; + real arg, poem, tel; + rvec cross_jk_kl; + + sin_ijk = SIN( p_ijk->theta ); + cos_ijk = COS( p_ijk->theta ); + sin_jkl = SIN( p_jkl->theta ); + cos_jkl = COS( p_jkl->theta ); + + /* omega */ + unnorm_cos_omega = -rvec_Dot( dvec_ij, dvec_jk ) * rvec_Dot( dvec_jk, dvec_kl ) + + SQR( r_jk ) * rvec_Dot( dvec_ij, dvec_kl ); + rvec_Cross( cross_jk_kl, dvec_jk, dvec_kl ); + unnorm_sin_omega = -r_jk * rvec_Dot( dvec_ij, cross_jk_kl ); + omega = atan2( unnorm_sin_omega, unnorm_cos_omega ); + + /* derivatives */ + /* coef for adjusments to cos_theta's */ + /* rla = r_ij, rlb = r_jk, rlc = r_kl, r4 = r_li; + coshd = cos_ijk, coshe = cos_jkl; + sinhd = sin_ijk, sinhe = sin_jkl; */ + htra = r_ij + cos_ijk * ( r_kl * cos_jkl - r_jk ); + htrb = r_jk - r_ij * cos_ijk - r_kl * cos_jkl; + htrc = r_kl + cos_jkl * ( r_ij * cos_ijk - r_jk ); + hthd = r_ij * sin_ijk * ( r_jk - r_kl * cos_jkl ); + hthe = r_kl * sin_jkl * ( r_jk - r_ij * cos_ijk ); + hnra = r_kl * sin_ijk * sin_jkl; + hnrc = r_ij * sin_ijk * sin_jkl; + hnhd = r_ij * r_kl * cos_ijk * sin_jkl; + hnhe = r_ij * r_kl * sin_ijk * cos_jkl; + + + poem = 2.0 * r_ij * r_kl * sin_ijk * sin_jkl; + if ( poem < 1e-20 ) poem = 1e-20; + + tel = (SQR(r_ij) + SQR(r_jk) + SQR(r_kl) - SQR(r_li)) - + 2.0 * ( r_ij * r_jk * cos_ijk - r_ij * r_kl * cos_ijk * cos_jkl + + r_jk * r_kl * cos_jkl ); + + arg = tel / poem; + if ( arg > 1.0 ) arg = 1.0; + if ( arg < -1.0 ) arg = -1.0; + + + /*fprintf( out_control->etor, + "%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e\n", + htra, htrb, htrc, hthd, hthe, hnra, hnrc, hnhd, hnhe ); + fprintf( out_control->etor, "%23.15e%23.15e%23.15e\n", + dvec_ij[0]/r_ij, dvec_ij[1]/r_ij, dvec_ij[2]/r_ij ); + fprintf( out_control->etor, "%23.15e%23.15e%23.15e\n", + -dvec_jk[0]/r_jk, -dvec_jk[1]/r_jk, -dvec_jk[2]/r_jk ); + fprintf( out_control->etor, "%23.15e%23.15e%23.15e\n", + -dvec_kl[0]/r_kl, -dvec_kl[1]/r_kl, -dvec_kl[2]/r_kl ); + fprintf( out_control->etor, "%23.15e%23.15e%23.15e%23.15e\n", + r_li, dvec_li[0], dvec_li[1], dvec_li[2] ); + fprintf( out_control->etor, "%23.15e%23.15e%23.15e%23.15e\n", + r_ij, r_jk, r_kl, r_li ); + fprintf( out_control->etor, "%23.15e%23.15e%23.15e%23.15e\n", + cos_ijk, cos_jkl, sin_ijk, sin_jkl ); + fprintf( out_control->etor, "%23.15e%23.15e%23.15e\n", + poem, tel, arg );*/ + /* fprintf( out_control->etor, "%23.15e%23.15e%23.15e\n", + -p_ijk->dcos_dk[0]/sin_ijk, + -p_ijk->dcos_dk[1]/sin_ijk, + -p_ijk->dcos_dk[2]/sin_ijk ); + fprintf( out_control->etor, "%23.15e%23.15e%23.15e\n", + -p_jkl->dcos_dk[0]/sin_jkl, + -p_jkl->dcos_dk[1]/sin_jkl, + -p_jkl->dcos_dk[2]/sin_jkl );*/ + + if ( sin_ijk >= 0 && sin_ijk <= MIN_SINE ) sin_ijk = MIN_SINE; + else if ( sin_ijk <= 0 && sin_ijk >= -MIN_SINE ) sin_ijk = -MIN_SINE; + if ( sin_jkl >= 0 && sin_jkl <= MIN_SINE ) sin_jkl = MIN_SINE; + else if ( sin_jkl <= 0 && sin_jkl >= -MIN_SINE ) sin_jkl = -MIN_SINE; + + // dcos_omega_di + rvec_ScaledSum( dcos_omega_di, (htra - arg * hnra) / r_ij, dvec_ij, -1., dvec_li ); + rvec_ScaledAdd( dcos_omega_di, -(hthd - arg * hnhd) / sin_ijk, p_ijk->dcos_dk ); + rvec_Scale( dcos_omega_di, 2.0 / poem, dcos_omega_di ); + + // dcos_omega_dj + rvec_ScaledSum( dcos_omega_dj, -(htra - arg * hnra) / r_ij, dvec_ij, + -htrb / r_jk, dvec_jk ); + rvec_ScaledAdd( dcos_omega_dj, -(hthd - arg * hnhd) / sin_ijk, p_ijk->dcos_dj ); + rvec_ScaledAdd( dcos_omega_dj, -(hthe - arg * hnhe) / sin_jkl, p_jkl->dcos_di ); + rvec_Scale( dcos_omega_dj, 2.0 / poem, dcos_omega_dj ); + + // dcos_omega_dk + rvec_ScaledSum( dcos_omega_dk, -(htrc - arg * hnrc) / r_kl, dvec_kl, + htrb / r_jk, dvec_jk ); + rvec_ScaledAdd( dcos_omega_dk, -(hthd - arg * hnhd) / sin_ijk, p_ijk->dcos_di ); + rvec_ScaledAdd( dcos_omega_dk, -(hthe - arg * hnhe) / sin_jkl, p_jkl->dcos_dj ); + rvec_Scale( dcos_omega_dk, 2.0 / poem, dcos_omega_dk ); + + // dcos_omega_dl + rvec_ScaledSum( dcos_omega_dl, (htrc - arg * hnrc) / r_kl, dvec_kl, 1., dvec_li ); + rvec_ScaledAdd( dcos_omega_dl, -(hthe - arg * hnhe) / sin_jkl, p_jkl->dcos_dk ); + rvec_Scale( dcos_omega_dl, 2.0 / poem, dcos_omega_dl ); + + return omega; + //return arg; } -void Four_Body_Interactions( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Four_Body_Interactions( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i, j, k, l, pi, pj, pk, pl, pij, plk; - int type_i, type_j, type_k, type_l; - int start_j, end_j, start_k, end_k; - int start_pj, end_pj, start_pk, end_pk; - int num_frb_intrs = 0; - - real Delta_j, Delta_k; - real r_ij, r_jk, r_kl, r_li; - real BOA_ij, BOA_jk, BOA_kl; - - real exp_tor2_ij, exp_tor2_jk, exp_tor2_kl; - real exp_tor1, exp_tor3_DjDk, exp_tor4_DjDk, exp_tor34_inv; - real exp_cot2_jk, exp_cot2_ij, exp_cot2_kl; - real fn10, f11_DjDk, dfn11, fn12; - - real theta_ijk, theta_jkl; - real sin_ijk, sin_jkl; - real cos_ijk, cos_jkl; - real tan_ijk_i, tan_jkl_i; - - real omega, cos_omega, cos2omega, cos3omega; - rvec dcos_omega_di, dcos_omega_dj, dcos_omega_dk, dcos_omega_dl; - - real CV, cmn, CEtors1, CEtors2, CEtors3, CEtors4; - real CEtors5, CEtors6, CEtors7, CEtors8, CEtors9; - real Cconj, CEconj1, CEconj2, CEconj3; - real CEconj4, CEconj5, CEconj6; - - real e_tor, e_con; - rvec dvec_li; - rvec force, ext_press; - ivec rel_box_jl; - // rtensor total_rtensor, temp_rtensor; - - four_body_header *fbh; - four_body_parameters *fbp; - bond_data *pbond_ij, *pbond_jk, *pbond_kl; - bond_order_data *bo_ij, *bo_jk, *bo_kl; - three_body_interaction_data *p_ijk, *p_jkl; - - real p_tor2 = system->reaxprm.gp.l[23]; - real p_tor3 = system->reaxprm.gp.l[24]; - real p_tor4 = system->reaxprm.gp.l[25]; - real p_cot2 = system->reaxprm.gp.l[27]; - - list *bonds = (*lists) + BONDS; - list *thb_intrs = (*lists) + THREE_BODIES; - - - for( j = 0; j < system->N; ++j ) { - type_j = system->atoms[j].type; - Delta_j = workspace->Delta_boc[j]; - start_j = Start_Index(j, bonds); - end_j = End_Index(j, bonds); - - - for( pk = start_j; pk < end_j; ++pk ) { - pbond_jk = &( bonds->select.bond_list[pk] ); - k = pbond_jk->nbr; - bo_jk = &( pbond_jk->bo_data ); - BOA_jk = bo_jk->BO - control->thb_cut; - - /* see if there are any 3-body interactions involving j&k - where j is the central atom. Otherwise there is no point in - trying to form a 4-body interaction out of this neighborhood */ - if( j < k && bo_jk->BO > control->thb_cut/*0*/ && - Num_Entries(pk, thb_intrs) ) { - start_k = Start_Index(k, bonds); - end_k = End_Index(k, bonds); - pj = pbond_jk->sym_index; // pj points to j on k's list - - /* do the same check as above: are there any 3-body interactions - involving k&j where k is the central atom */ - if( Num_Entries(pj, thb_intrs) ) { - type_k = system->atoms[k].type; - Delta_k = workspace->Delta_boc[k]; - r_jk = pbond_jk->d; - - start_pk = Start_Index(pk, thb_intrs ); - end_pk = End_Index(pk, thb_intrs ); - start_pj = Start_Index(pj, thb_intrs ); - end_pj = End_Index(pj, thb_intrs ); - - exp_tor2_jk = EXP( -p_tor2 * BOA_jk ); - exp_cot2_jk = EXP( -p_cot2 * SQR(BOA_jk - 1.5) ); - exp_tor3_DjDk = EXP( -p_tor3 * (Delta_j + Delta_k) ); - exp_tor4_DjDk = EXP( p_tor4 * (Delta_j + Delta_k) ); - exp_tor34_inv = 1.0 / (1.0 + exp_tor3_DjDk + exp_tor4_DjDk); - f11_DjDk = (2.0 + exp_tor3_DjDk) * exp_tor34_inv; - - - /* pick i up from j-k interaction where j is the centre atom */ - for( pi = start_pk; pi < end_pk; ++pi ) { - p_ijk = &( thb_intrs->select.three_body_list[pi] ); - pij = p_ijk->pthb; // pij is pointer to i on j's bond_list - pbond_ij = &( bonds->select.bond_list[pij] ); - bo_ij = &( pbond_ij->bo_data ); - - - if( bo_ij->BO > control->thb_cut/*0*/ ) { - i = p_ijk->thb; - type_i = system->atoms[i].type; - r_ij = pbond_ij->d; - BOA_ij = bo_ij->BO - control->thb_cut; - - theta_ijk = p_ijk->theta; - sin_ijk = SIN( theta_ijk ); - cos_ijk = COS( theta_ijk ); - //tan_ijk_i = 1. / TAN( theta_ijk ); - if( sin_ijk >= 0 && sin_ijk <= MIN_SINE ) - tan_ijk_i = cos_ijk / MIN_SINE; - else if( sin_ijk <= 0 && sin_ijk >= -MIN_SINE ) - tan_ijk_i = cos_ijk / -MIN_SINE; - else tan_ijk_i = cos_ijk / sin_ijk; - - exp_tor2_ij = EXP( -p_tor2 * BOA_ij ); - exp_cot2_ij = EXP( -p_cot2 * SQR(BOA_ij -1.5) ); - - /* pick l up from j-k intr. where k is the centre */ - for( pl = start_pj; pl < end_pj; ++pl ) { - p_jkl = &( thb_intrs->select.three_body_list[pl] ); - l = p_jkl->thb; - plk = p_jkl->pthb; //pointer to l on k's bond_list! - pbond_kl = &( bonds->select.bond_list[plk] ); - bo_kl = &( pbond_kl->bo_data ); - type_l = system->atoms[l].type; - fbh = &(system->reaxprm.fbp[type_i][type_j][type_k][type_l]); - fbp = &(system->reaxprm.fbp[type_i][type_j] - [type_k][type_l].prm[0]); - - if( i != l && fbh->cnt && bo_kl->BO > control->thb_cut/*0*/ && - bo_ij->BO * bo_jk->BO * bo_kl->BO > control->thb_cut/*0*/ ){ - ++num_frb_intrs; - r_kl = pbond_kl->d; - BOA_kl = bo_kl->BO - control->thb_cut; - - theta_jkl = p_jkl->theta; - sin_jkl = SIN( theta_jkl ); - cos_jkl = COS( theta_jkl ); - //tan_jkl_i = 1. / TAN( theta_jkl ); - if( sin_jkl >= 0 && sin_jkl <= MIN_SINE ) - tan_jkl_i = cos_jkl / MIN_SINE; - else if( sin_jkl <= 0 && sin_jkl >= -MIN_SINE ) - tan_jkl_i = cos_jkl / -MIN_SINE; - else tan_jkl_i = cos_jkl /sin_jkl; - - Sq_Distance_on_T3( system->atoms[l].x, system->atoms[i].x, - &(system->box), dvec_li ); - r_li = rvec_Norm( dvec_li ); - - - /* omega and its derivative */ - //cos_omega=Calculate_Omega(pbond_ij->dvec,r_ij,pbond_jk->dvec, - omega = Calculate_Omega(pbond_ij->dvec, r_ij, pbond_jk->dvec, - r_jk, pbond_kl->dvec, r_kl, - dvec_li, r_li, p_ijk, p_jkl, - dcos_omega_di, dcos_omega_dj, - dcos_omega_dk, dcos_omega_dl, - out_control); - cos_omega = COS( omega ); - cos2omega = COS( 2. * omega ); - cos3omega = COS( 3. * omega ); - /* end omega calculations */ - - /* torsion energy */ - exp_tor1 = EXP(fbp->p_tor1 * SQR(2.-bo_jk->BO_pi-f11_DjDk)); - exp_tor2_kl = EXP( -p_tor2 * BOA_kl ); - exp_cot2_kl = EXP( -p_cot2 * SQR(BOA_kl-1.5) ); - fn10 = (1.0 - exp_tor2_ij) * (1.0 - exp_tor2_jk) * - (1.0 - exp_tor2_kl); - - CV = 0.5 * ( fbp->V1 * (1.0 + cos_omega) + - fbp->V2 * exp_tor1 * (1.0 - cos2omega) + - fbp->V3 * (1.0 + cos3omega) ); - //CV = 0.5 * fbp->V1 * (1.0 + cos_omega) + - // fbp->V2 * exp_tor1 * (1.0 - SQR(cos_omega)) + - // fbp->V3 * (0.5 + 2.0*CUBE(cos_omega) - 1.5 * cos_omega); - - data->E_Tor += e_tor = fn10 * sin_ijk * sin_jkl * CV; - - dfn11 = (-p_tor3 * exp_tor3_DjDk + - (p_tor3 * exp_tor3_DjDk - p_tor4 * exp_tor4_DjDk) * - (2.+exp_tor3_DjDk) * exp_tor34_inv) * exp_tor34_inv; - - CEtors1 = sin_ijk * sin_jkl * CV; - - CEtors2 = -fn10 * 2.0 * fbp->p_tor1 * fbp->V2 * exp_tor1 * - (2.0 - bo_jk->BO_pi - f11_DjDk) * (1.0 - SQR(cos_omega)) * - sin_ijk * sin_jkl; - - CEtors3 = CEtors2 * dfn11; - - CEtors4 = CEtors1 * p_tor2 * exp_tor2_ij * - (1.0 - exp_tor2_jk) * (1.0 - exp_tor2_kl); - - CEtors5 = CEtors1 * p_tor2 * exp_tor2_jk * - (1.0 - exp_tor2_ij) * (1.0 - exp_tor2_kl); - - CEtors6 = CEtors1 * p_tor2 * exp_tor2_kl * - (1.0 - exp_tor2_ij) * (1.0 - exp_tor2_jk); - - cmn = -fn10 * CV; - CEtors7 = cmn * sin_jkl * tan_ijk_i; - CEtors8 = cmn * sin_ijk * tan_jkl_i; - CEtors9 = fn10 * sin_ijk * sin_jkl * - (0.5 * fbp->V1 - 2.0 * fbp->V2 * exp_tor1 * cos_omega + - 1.5 * fbp->V3 * (cos2omega + 2. * SQR(cos_omega))); - //cmn = -fn10 * CV; - //CEtors7 = cmn * sin_jkl * cos_ijk; - //CEtors8 = cmn * sin_ijk * cos_jkl; - //CEtors9 = fn10 * sin_ijk * sin_jkl * - // (0.5 * fbp->V1 - 2.0 * fbp->V2 * exp_tor1 * cos_omega + - // fbp->V3 * (6*SQR(cos_omega) - 1.50)); - /* end of torsion energy */ - - - /* 4-body conjugation energy */ - fn12 = exp_cot2_ij * exp_cot2_jk * exp_cot2_kl; - data->E_Con += e_con = fbp->p_cot1 * fn12 * - (1. + (SQR(cos_omega)-1.) * sin_ijk*sin_jkl); - - Cconj = -2.0 * fn12 * fbp->p_cot1 * p_cot2 * - (1. + (SQR(cos_omega)-1.) * sin_ijk*sin_jkl); - - CEconj1 = Cconj * (BOA_ij - 1.5e0); - CEconj2 = Cconj * (BOA_jk - 1.5e0); - CEconj3 = Cconj * (BOA_kl - 1.5e0); - - CEconj4 = -fbp->p_cot1 * fn12 * - (SQR(cos_omega) - 1.0) * sin_jkl * tan_ijk_i; - CEconj5 = -fbp->p_cot1 * fn12 * - (SQR(cos_omega) - 1.0) * sin_ijk * tan_jkl_i; - //CEconj4 = -fbp->p_cot1 * fn12 * - // (SQR(cos_omega) - 1.0) * sin_jkl * cos_ijk; - //CEconj5 = -fbp->p_cot1 * fn12 * - // (SQR(cos_omega) - 1.0) * sin_ijk * cos_jkl; - CEconj6 = 2.0 * fbp->p_cot1 * fn12 * - cos_omega * sin_ijk * sin_jkl; - /* end 4-body conjugation energy */ - - //fprintf(stdout, "%6d %6d %6d %6d %7.3f %7.3f %7.3f %7.3f ", - // workspace->orig_id[i], workspace->orig_id[j], - // workspace->orig_id[k], workspace->orig_id[l], - // omega, cos_omega, cos2omega, cos3omega ); - //fprintf(stdout, - // "%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f\n", - // CEtors2, CEtors3, CEtors4, CEtors5, - // CEtors6, CEtors7, CEtors8, CEtors9 ); - //fprintf(stdout, "%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f\n", - // theta_ijk, theta_jkl, sin_ijk, - // sin_jkl, cos_jkl, tan_jkl_i ); - - /* forces */ - bo_jk->Cdbopi += CEtors2; - workspace->CdDelta[j] += CEtors3; - workspace->CdDelta[k] += CEtors3; - bo_ij->Cdbo += (CEtors4 + CEconj1); - bo_jk->Cdbo += (CEtors5 + CEconj2); - bo_kl->Cdbo += (CEtors6 + CEconj3); - - if( control->ensemble == NVE || control->ensemble == NVT || control->ensemble == bNVT ) { - /* dcos_theta_ijk */ - rvec_ScaledAdd( system->atoms[i].f, - CEtors7 + CEconj4, p_ijk->dcos_dk ); - rvec_ScaledAdd( system->atoms[j].f, - CEtors7 + CEconj4, p_ijk->dcos_dj ); - rvec_ScaledAdd( system->atoms[k].f, - CEtors7 + CEconj4, p_ijk->dcos_di ); - - /* dcos_theta_jkl */ - rvec_ScaledAdd( system->atoms[j].f, - CEtors8 + CEconj5, p_jkl->dcos_di ); - rvec_ScaledAdd( system->atoms[k].f, - CEtors8 + CEconj5, p_jkl->dcos_dj ); - rvec_ScaledAdd( system->atoms[l].f, - CEtors8 + CEconj5, p_jkl->dcos_dk ); - - /* dcos_omega */ - rvec_ScaledAdd( system->atoms[i].f, - CEtors9 + CEconj6, dcos_omega_di ); - rvec_ScaledAdd( system->atoms[j].f, - CEtors9 + CEconj6, dcos_omega_dj ); - rvec_ScaledAdd( system->atoms[k].f, - CEtors9 + CEconj6, dcos_omega_dk ); - rvec_ScaledAdd( system->atoms[l].f, - CEtors9 + CEconj6, dcos_omega_dl ); - } - else { - ivec_Sum(rel_box_jl, pbond_jk->rel_box, pbond_kl->rel_box); - - /* dcos_theta_ijk */ - rvec_Scale( force, CEtors7 + CEconj4, p_ijk->dcos_dk ); - rvec_Add( system->atoms[i].f, force ); - rvec_iMultiply( ext_press, pbond_ij->rel_box, force ); - rvec_Add( data->ext_press, ext_press ); - - rvec_ScaledAdd( system->atoms[j].f, - CEtors7 + CEconj4, p_ijk->dcos_dj ); - - rvec_Scale( force, CEtors7 + CEconj4, p_ijk->dcos_di ); - rvec_Add( system->atoms[k].f, force ); - rvec_iMultiply( ext_press, pbond_jk->rel_box, force ); - rvec_Add( data->ext_press, ext_press ); - - - /* dcos_theta_jkl */ - rvec_ScaledAdd( system->atoms[j].f, - CEtors8 + CEconj5, p_jkl->dcos_di ); - - rvec_Scale( force, CEtors8 + CEconj5, p_jkl->dcos_dj ); - rvec_Add( system->atoms[k].f, force ); - rvec_iMultiply( ext_press, pbond_jk->rel_box, force ); - rvec_Add( data->ext_press, ext_press ); - - rvec_Scale( force, CEtors8 + CEconj5, p_jkl->dcos_dk ); - rvec_Add( system->atoms[l].f, force ); - rvec_iMultiply( ext_press, rel_box_jl, force ); - rvec_Add( data->ext_press, ext_press ); - - - /* dcos_omega */ - rvec_Scale( force, CEtors9 + CEconj6, dcos_omega_di ); - rvec_Add( system->atoms[i].f, force ); - rvec_iMultiply( ext_press, pbond_ij->rel_box, force ); - rvec_Add( data->ext_press, ext_press ); - - rvec_ScaledAdd( system->atoms[j].f, - CEtors9 + CEconj6, dcos_omega_dj ); - - rvec_Scale( force, CEtors9 + CEconj6, dcos_omega_dk ); - rvec_Add( system->atoms[k].f, force ); - rvec_iMultiply( ext_press, pbond_jk->rel_box, force ); - rvec_Add( data->ext_press, ext_press ); - - rvec_Scale( force, CEtors9 + CEconj6, dcos_omega_dl ); - rvec_Add( system->atoms[l].f, force ); - rvec_iMultiply( ext_press, rel_box_jl, force ); - rvec_Add( data->ext_press, ext_press ); - - - /* This part is intended for a fully-flexible box */ - /* rvec_ScaledSum( temp_rvec, - CEtors7 + CEconj4, p_ijk->dcos_dk, // i - CEtors9 + CEconj6, dcos_omega_di ); - rvec_OuterProduct( temp_rtensor, - temp_rvec, system->atoms[i].x ); - rtensor_Copy( total_rtensor, temp_rtensor ); - - rvec_ScaledSum( temp_rvec, - CEtors7 + CEconj4, p_ijk->dcos_dj, // j - CEtors8 + CEconj5, p_jkl->dcos_di ); - rvec_ScaledAdd( temp_rvec, - CEtors9 + CEconj6, dcos_omega_dj ); - rvec_OuterProduct( temp_rtensor, - temp_rvec, system->atoms[j].x ); - rtensor_Add( total_rtensor, temp_rtensor ); - - rvec_ScaledSum( temp_rvec, - CEtors7 + CEconj4, p_ijk->dcos_di, // k - CEtors8 + CEconj5, p_jkl->dcos_dj ); - rvec_ScaledAdd( temp_rvec, - CEtors9 + CEconj6, dcos_omega_dk ); - rvec_OuterProduct( temp_rtensor, - temp_rvec, system->atoms[k].x ); - rtensor_Add( total_rtensor, temp_rtensor ); - - rvec_ScaledSum( temp_rvec, - CEtors8 + CEconj5, p_jkl->dcos_dk, // l - CEtors9 + CEconj6, dcos_omega_dl ); - rvec_OuterProduct( temp_rtensor, - temp_rvec, system->atoms[l].x ); - rtensor_Copy( total_rtensor, temp_rtensor ); - - if( pbond_ij->imaginary || pbond_jk->imaginary || - pbond_kl->imaginary ) - rtensor_ScaledAdd( data->flex_bar.P, -1., total_rtensor ); - else - rtensor_Add( data->flex_bar.P, total_rtensor ); */ - } - + int i, j, k, l, pi, pj, pk, pl, pij, plk; + int type_i, type_j, type_k, type_l; + int start_j, end_j, start_k, end_k; + int start_pj, end_pj, start_pk, end_pk; + int num_frb_intrs = 0; + + real Delta_j, Delta_k; + real r_ij, r_jk, r_kl, r_li; + real BOA_ij, BOA_jk, BOA_kl; + + real exp_tor2_ij, exp_tor2_jk, exp_tor2_kl; + real exp_tor1, exp_tor3_DjDk, exp_tor4_DjDk, exp_tor34_inv; + real exp_cot2_jk, exp_cot2_ij, exp_cot2_kl; + real fn10, f11_DjDk, dfn11, fn12; + + real theta_ijk, theta_jkl; + real sin_ijk, sin_jkl; + real cos_ijk, cos_jkl; + real tan_ijk_i, tan_jkl_i; + + real omega, cos_omega, cos2omega, cos3omega; + rvec dcos_omega_di, dcos_omega_dj, dcos_omega_dk, dcos_omega_dl; + + real CV, cmn, CEtors1, CEtors2, CEtors3, CEtors4; + real CEtors5, CEtors6, CEtors7, CEtors8, CEtors9; + real Cconj, CEconj1, CEconj2, CEconj3; + real CEconj4, CEconj5, CEconj6; + + real e_tor, e_con; + rvec dvec_li; + rvec force, ext_press; + ivec rel_box_jl; + // rtensor total_rtensor, temp_rtensor; + + four_body_header *fbh; + four_body_parameters *fbp; + bond_data *pbond_ij, *pbond_jk, *pbond_kl; + bond_order_data *bo_ij, *bo_jk, *bo_kl; + three_body_interaction_data *p_ijk, *p_jkl; + + real p_tor2 = system->reaxprm.gp.l[23]; + real p_tor3 = system->reaxprm.gp.l[24]; + real p_tor4 = system->reaxprm.gp.l[25]; + real p_cot2 = system->reaxprm.gp.l[27]; + + list *bonds = (*lists) + BONDS; + list *thb_intrs = (*lists) + THREE_BODIES; + + + for ( j = 0; j < system->N; ++j ) + { + type_j = system->atoms[j].type; + Delta_j = workspace->Delta_boc[j]; + start_j = Start_Index(j, bonds); + end_j = End_Index(j, bonds); + + + for ( pk = start_j; pk < end_j; ++pk ) + { + pbond_jk = &( bonds->select.bond_list[pk] ); + k = pbond_jk->nbr; + bo_jk = &( pbond_jk->bo_data ); + BOA_jk = bo_jk->BO - control->thb_cut; + + /* see if there are any 3-body interactions involving j&k + where j is the central atom. Otherwise there is no point in + trying to form a 4-body interaction out of this neighborhood */ + if ( j < k && bo_jk->BO > control->thb_cut/*0*/ && + Num_Entries(pk, thb_intrs) ) + { + start_k = Start_Index(k, bonds); + end_k = End_Index(k, bonds); + pj = pbond_jk->sym_index; // pj points to j on k's list + + /* do the same check as above: are there any 3-body interactions + involving k&j where k is the central atom */ + if ( Num_Entries(pj, thb_intrs) ) + { + type_k = system->atoms[k].type; + Delta_k = workspace->Delta_boc[k]; + r_jk = pbond_jk->d; + + start_pk = Start_Index(pk, thb_intrs ); + end_pk = End_Index(pk, thb_intrs ); + start_pj = Start_Index(pj, thb_intrs ); + end_pj = End_Index(pj, thb_intrs ); + + exp_tor2_jk = EXP( -p_tor2 * BOA_jk ); + exp_cot2_jk = EXP( -p_cot2 * SQR(BOA_jk - 1.5) ); + exp_tor3_DjDk = EXP( -p_tor3 * (Delta_j + Delta_k) ); + exp_tor4_DjDk = EXP( p_tor4 * (Delta_j + Delta_k) ); + exp_tor34_inv = 1.0 / (1.0 + exp_tor3_DjDk + exp_tor4_DjDk); + f11_DjDk = (2.0 + exp_tor3_DjDk) * exp_tor34_inv; + + + /* pick i up from j-k interaction where j is the centre atom */ + for ( pi = start_pk; pi < end_pk; ++pi ) + { + p_ijk = &( thb_intrs->select.three_body_list[pi] ); + pij = p_ijk->pthb; // pij is pointer to i on j's bond_list + pbond_ij = &( bonds->select.bond_list[pij] ); + bo_ij = &( pbond_ij->bo_data ); + + + if ( bo_ij->BO > control->thb_cut/*0*/ ) + { + i = p_ijk->thb; + type_i = system->atoms[i].type; + r_ij = pbond_ij->d; + BOA_ij = bo_ij->BO - control->thb_cut; + + theta_ijk = p_ijk->theta; + sin_ijk = SIN( theta_ijk ); + cos_ijk = COS( theta_ijk ); + //tan_ijk_i = 1. / TAN( theta_ijk ); + if ( sin_ijk >= 0 && sin_ijk <= MIN_SINE ) + tan_ijk_i = cos_ijk / MIN_SINE; + else if ( sin_ijk <= 0 && sin_ijk >= -MIN_SINE ) + tan_ijk_i = cos_ijk / -MIN_SINE; + else tan_ijk_i = cos_ijk / sin_ijk; + + exp_tor2_ij = EXP( -p_tor2 * BOA_ij ); + exp_cot2_ij = EXP( -p_cot2 * SQR(BOA_ij - 1.5) ); + + /* pick l up from j-k intr. where k is the centre */ + for ( pl = start_pj; pl < end_pj; ++pl ) + { + p_jkl = &( thb_intrs->select.three_body_list[pl] ); + l = p_jkl->thb; + plk = p_jkl->pthb; //pointer to l on k's bond_list! + pbond_kl = &( bonds->select.bond_list[plk] ); + bo_kl = &( pbond_kl->bo_data ); + type_l = system->atoms[l].type; + fbh = &(system->reaxprm.fbp[type_i][type_j][type_k][type_l]); + fbp = &(system->reaxprm.fbp[type_i][type_j] + [type_k][type_l].prm[0]); + + if ( i != l && fbh->cnt && bo_kl->BO > control->thb_cut/*0*/ && + bo_ij->BO * bo_jk->BO * bo_kl->BO > control->thb_cut/*0*/ ) + { + ++num_frb_intrs; + r_kl = pbond_kl->d; + BOA_kl = bo_kl->BO - control->thb_cut; + + theta_jkl = p_jkl->theta; + sin_jkl = SIN( theta_jkl ); + cos_jkl = COS( theta_jkl ); + //tan_jkl_i = 1. / TAN( theta_jkl ); + if ( sin_jkl >= 0 && sin_jkl <= MIN_SINE ) + tan_jkl_i = cos_jkl / MIN_SINE; + else if ( sin_jkl <= 0 && sin_jkl >= -MIN_SINE ) + tan_jkl_i = cos_jkl / -MIN_SINE; + else tan_jkl_i = cos_jkl / sin_jkl; + + Sq_Distance_on_T3( system->atoms[l].x, system->atoms[i].x, + &(system->box), dvec_li ); + r_li = rvec_Norm( dvec_li ); + + + /* omega and its derivative */ + //cos_omega=Calculate_Omega(pbond_ij->dvec,r_ij,pbond_jk->dvec, + omega = Calculate_Omega(pbond_ij->dvec, r_ij, pbond_jk->dvec, + r_jk, pbond_kl->dvec, r_kl, + dvec_li, r_li, p_ijk, p_jkl, + dcos_omega_di, dcos_omega_dj, + dcos_omega_dk, dcos_omega_dl, + out_control); + cos_omega = COS( omega ); + cos2omega = COS( 2. * omega ); + cos3omega = COS( 3. * omega ); + /* end omega calculations */ + + /* torsion energy */ + exp_tor1 = EXP(fbp->p_tor1 * SQR(2. - bo_jk->BO_pi - f11_DjDk)); + exp_tor2_kl = EXP( -p_tor2 * BOA_kl ); + exp_cot2_kl = EXP( -p_cot2 * SQR(BOA_kl - 1.5) ); + fn10 = (1.0 - exp_tor2_ij) * (1.0 - exp_tor2_jk) * + (1.0 - exp_tor2_kl); + + CV = 0.5 * ( fbp->V1 * (1.0 + cos_omega) + + fbp->V2 * exp_tor1 * (1.0 - cos2omega) + + fbp->V3 * (1.0 + cos3omega) ); + //CV = 0.5 * fbp->V1 * (1.0 + cos_omega) + + // fbp->V2 * exp_tor1 * (1.0 - SQR(cos_omega)) + + // fbp->V3 * (0.5 + 2.0*CUBE(cos_omega) - 1.5 * cos_omega); + + data->E_Tor += e_tor = fn10 * sin_ijk * sin_jkl * CV; + + dfn11 = (-p_tor3 * exp_tor3_DjDk + + (p_tor3 * exp_tor3_DjDk - p_tor4 * exp_tor4_DjDk) * + (2. + exp_tor3_DjDk) * exp_tor34_inv) * exp_tor34_inv; + + CEtors1 = sin_ijk * sin_jkl * CV; + + CEtors2 = -fn10 * 2.0 * fbp->p_tor1 * fbp->V2 * exp_tor1 * + (2.0 - bo_jk->BO_pi - f11_DjDk) * (1.0 - SQR(cos_omega)) * + sin_ijk * sin_jkl; + + CEtors3 = CEtors2 * dfn11; + + CEtors4 = CEtors1 * p_tor2 * exp_tor2_ij * + (1.0 - exp_tor2_jk) * (1.0 - exp_tor2_kl); + + CEtors5 = CEtors1 * p_tor2 * exp_tor2_jk * + (1.0 - exp_tor2_ij) * (1.0 - exp_tor2_kl); + + CEtors6 = CEtors1 * p_tor2 * exp_tor2_kl * + (1.0 - exp_tor2_ij) * (1.0 - exp_tor2_jk); + + cmn = -fn10 * CV; + CEtors7 = cmn * sin_jkl * tan_ijk_i; + CEtors8 = cmn * sin_ijk * tan_jkl_i; + CEtors9 = fn10 * sin_ijk * sin_jkl * + (0.5 * fbp->V1 - 2.0 * fbp->V2 * exp_tor1 * cos_omega + + 1.5 * fbp->V3 * (cos2omega + 2. * SQR(cos_omega))); + //cmn = -fn10 * CV; + //CEtors7 = cmn * sin_jkl * cos_ijk; + //CEtors8 = cmn * sin_ijk * cos_jkl; + //CEtors9 = fn10 * sin_ijk * sin_jkl * + // (0.5 * fbp->V1 - 2.0 * fbp->V2 * exp_tor1 * cos_omega + + // fbp->V3 * (6*SQR(cos_omega) - 1.50)); + /* end of torsion energy */ + + + /* 4-body conjugation energy */ + fn12 = exp_cot2_ij * exp_cot2_jk * exp_cot2_kl; + data->E_Con += e_con = fbp->p_cot1 * fn12 * + (1. + (SQR(cos_omega) - 1.) * sin_ijk * sin_jkl); + + Cconj = -2.0 * fn12 * fbp->p_cot1 * p_cot2 * + (1. + (SQR(cos_omega) - 1.) * sin_ijk * sin_jkl); + + CEconj1 = Cconj * (BOA_ij - 1.5e0); + CEconj2 = Cconj * (BOA_jk - 1.5e0); + CEconj3 = Cconj * (BOA_kl - 1.5e0); + + CEconj4 = -fbp->p_cot1 * fn12 * + (SQR(cos_omega) - 1.0) * sin_jkl * tan_ijk_i; + CEconj5 = -fbp->p_cot1 * fn12 * + (SQR(cos_omega) - 1.0) * sin_ijk * tan_jkl_i; + //CEconj4 = -fbp->p_cot1 * fn12 * + // (SQR(cos_omega) - 1.0) * sin_jkl * cos_ijk; + //CEconj5 = -fbp->p_cot1 * fn12 * + // (SQR(cos_omega) - 1.0) * sin_ijk * cos_jkl; + CEconj6 = 2.0 * fbp->p_cot1 * fn12 * + cos_omega * sin_ijk * sin_jkl; + /* end 4-body conjugation energy */ + + //fprintf(stdout, "%6d %6d %6d %6d %7.3f %7.3f %7.3f %7.3f ", + // workspace->orig_id[i], workspace->orig_id[j], + // workspace->orig_id[k], workspace->orig_id[l], + // omega, cos_omega, cos2omega, cos3omega ); + //fprintf(stdout, + // "%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f\n", + // CEtors2, CEtors3, CEtors4, CEtors5, + // CEtors6, CEtors7, CEtors8, CEtors9 ); + //fprintf(stdout, "%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f\n", + // theta_ijk, theta_jkl, sin_ijk, + // sin_jkl, cos_jkl, tan_jkl_i ); + + /* forces */ + bo_jk->Cdbopi += CEtors2; + workspace->CdDelta[j] += CEtors3; + workspace->CdDelta[k] += CEtors3; + bo_ij->Cdbo += (CEtors4 + CEconj1); + bo_jk->Cdbo += (CEtors5 + CEconj2); + bo_kl->Cdbo += (CEtors6 + CEconj3); + + if ( control->ensemble == NVE || control->ensemble == NVT || control->ensemble == bNVT ) + { + /* dcos_theta_ijk */ + rvec_ScaledAdd( system->atoms[i].f, + CEtors7 + CEconj4, p_ijk->dcos_dk ); + rvec_ScaledAdd( system->atoms[j].f, + CEtors7 + CEconj4, p_ijk->dcos_dj ); + rvec_ScaledAdd( system->atoms[k].f, + CEtors7 + CEconj4, p_ijk->dcos_di ); + + /* dcos_theta_jkl */ + rvec_ScaledAdd( system->atoms[j].f, + CEtors8 + CEconj5, p_jkl->dcos_di ); + rvec_ScaledAdd( system->atoms[k].f, + CEtors8 + CEconj5, p_jkl->dcos_dj ); + rvec_ScaledAdd( system->atoms[l].f, + CEtors8 + CEconj5, p_jkl->dcos_dk ); + + /* dcos_omega */ + rvec_ScaledAdd( system->atoms[i].f, + CEtors9 + CEconj6, dcos_omega_di ); + rvec_ScaledAdd( system->atoms[j].f, + CEtors9 + CEconj6, dcos_omega_dj ); + rvec_ScaledAdd( system->atoms[k].f, + CEtors9 + CEconj6, dcos_omega_dk ); + rvec_ScaledAdd( system->atoms[l].f, + CEtors9 + CEconj6, dcos_omega_dl ); + } + else + { + ivec_Sum(rel_box_jl, pbond_jk->rel_box, pbond_kl->rel_box); + + /* dcos_theta_ijk */ + rvec_Scale( force, CEtors7 + CEconj4, p_ijk->dcos_dk ); + rvec_Add( system->atoms[i].f, force ); + rvec_iMultiply( ext_press, pbond_ij->rel_box, force ); + rvec_Add( data->ext_press, ext_press ); + + rvec_ScaledAdd( system->atoms[j].f, + CEtors7 + CEconj4, p_ijk->dcos_dj ); + + rvec_Scale( force, CEtors7 + CEconj4, p_ijk->dcos_di ); + rvec_Add( system->atoms[k].f, force ); + rvec_iMultiply( ext_press, pbond_jk->rel_box, force ); + rvec_Add( data->ext_press, ext_press ); + + + /* dcos_theta_jkl */ + rvec_ScaledAdd( system->atoms[j].f, + CEtors8 + CEconj5, p_jkl->dcos_di ); + + rvec_Scale( force, CEtors8 + CEconj5, p_jkl->dcos_dj ); + rvec_Add( system->atoms[k].f, force ); + rvec_iMultiply( ext_press, pbond_jk->rel_box, force ); + rvec_Add( data->ext_press, ext_press ); + + rvec_Scale( force, CEtors8 + CEconj5, p_jkl->dcos_dk ); + rvec_Add( system->atoms[l].f, force ); + rvec_iMultiply( ext_press, rel_box_jl, force ); + rvec_Add( data->ext_press, ext_press ); + + + /* dcos_omega */ + rvec_Scale( force, CEtors9 + CEconj6, dcos_omega_di ); + rvec_Add( system->atoms[i].f, force ); + rvec_iMultiply( ext_press, pbond_ij->rel_box, force ); + rvec_Add( data->ext_press, ext_press ); + + rvec_ScaledAdd( system->atoms[j].f, + CEtors9 + CEconj6, dcos_omega_dj ); + + rvec_Scale( force, CEtors9 + CEconj6, dcos_omega_dk ); + rvec_Add( system->atoms[k].f, force ); + rvec_iMultiply( ext_press, pbond_jk->rel_box, force ); + rvec_Add( data->ext_press, ext_press ); + + rvec_Scale( force, CEtors9 + CEconj6, dcos_omega_dl ); + rvec_Add( system->atoms[l].f, force ); + rvec_iMultiply( ext_press, rel_box_jl, force ); + rvec_Add( data->ext_press, ext_press ); + + + /* This part is intended for a fully-flexible box */ + /* rvec_ScaledSum( temp_rvec, + CEtors7 + CEconj4, p_ijk->dcos_dk, // i + CEtors9 + CEconj6, dcos_omega_di ); + rvec_OuterProduct( temp_rtensor, + temp_rvec, system->atoms[i].x ); + rtensor_Copy( total_rtensor, temp_rtensor ); + + rvec_ScaledSum( temp_rvec, + CEtors7 + CEconj4, p_ijk->dcos_dj, // j + CEtors8 + CEconj5, p_jkl->dcos_di ); + rvec_ScaledAdd( temp_rvec, + CEtors9 + CEconj6, dcos_omega_dj ); + rvec_OuterProduct( temp_rtensor, + temp_rvec, system->atoms[j].x ); + rtensor_Add( total_rtensor, temp_rtensor ); + + rvec_ScaledSum( temp_rvec, + CEtors7 + CEconj4, p_ijk->dcos_di, // k + CEtors8 + CEconj5, p_jkl->dcos_dj ); + rvec_ScaledAdd( temp_rvec, + CEtors9 + CEconj6, dcos_omega_dk ); + rvec_OuterProduct( temp_rtensor, + temp_rvec, system->atoms[k].x ); + rtensor_Add( total_rtensor, temp_rtensor ); + + rvec_ScaledSum( temp_rvec, + CEtors8 + CEconj5, p_jkl->dcos_dk, // l + CEtors9 + CEconj6, dcos_omega_dl ); + rvec_OuterProduct( temp_rtensor, + temp_rvec, system->atoms[l].x ); + rtensor_Copy( total_rtensor, temp_rtensor ); + + if( pbond_ij->imaginary || pbond_jk->imaginary || + pbond_kl->imaginary ) + rtensor_ScaledAdd( data->flex_bar.P, -1., total_rtensor ); + else + rtensor_Add( data->flex_bar.P, total_rtensor ); */ + } + #ifdef TEST_ENERGY - /*fprintf( out_control->etor, - //"%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f\n", - //r_ij, r_jk, r_kl, - "%12.8f%12.8f%12.8f%12.8f\n", - cos_ijk, cos_jkl, sin_ijk, sin_jkl );*/ - // fprintf( out_control->etor, "%12.8f\n", dfn11 ); - fprintf( out_control->etor, "%12.8f%12.8f%12.8f\n", - fn10, cos_omega, CV ); - - fprintf( out_control->etor, - "%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f\n", - CEtors2, CEtors3, CEtors4, CEtors5, - CEtors6, CEtors7, CEtors8, CEtors9 ); - - /* fprintf( out_control->etor, - "%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f\n", - htra, htrb, htrc, hthd, hthe, hnra, hnrc, hnhd, hnhe ); */ - - fprintf( out_control->etor, - "%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f\n", - CEconj1, CEconj2, CEconj3, CEconj4, CEconj5, CEconj6 ); - /* fprintf(out_control->etor,"%23.15e%23.15e%23.15e%23.15e\n", - fbp->V1, fbp->V2, fbp->V3, fbp->p_tor1 );*/ - - fprintf( out_control->etor, - //"%6d%6d%6d%6d%23.15e%23.15e%23.15e%23.15e\n", - "%6d%6d%6d%6d%12.8f%12.8f\n", - workspace->orig_id[i], workspace->orig_id[j], - workspace->orig_id[k], workspace->orig_id[l], - e_tor, e_con ); - //RAD2DEG(omega), BOA_jk, e_tor, data->E_Tor ); - - fprintf( out_control->econ, - "%6d%6d%6d%6d%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e\n", - workspace->orig_id[i], workspace->orig_id[j], - workspace->orig_id[k], workspace->orig_id[l], - RAD2DEG(omega), BOA_ij, BOA_jk, BOA_kl, - e_con,data->E_Con ); - - /* fprintf( out_control->etor, - "%12.8f%12.8f%12.8f\n%12.8f%12.8f%12.8f\n%12.8f%12.8f%12.8f\n", - (CEtors7 + CEconj4)*p_ijk->dcos_dk[0], - (CEtors7 + CEconj4)*p_ijk->dcos_dk[1], - (CEtors7 + CEconj4)*p_ijk->dcos_dk[2], - (CEtors7 + CEconj4)*p_ijk->dcos_dj[0], - (CEtors7 + CEconj4)*p_ijk->dcos_dj[1], - (CEtors7 + CEconj4)*p_ijk->dcos_dj[2], - (CEtors7 + CEconj4)*p_ijk->dcos_di[0], - (CEtors7 + CEconj4)*p_ijk->dcos_di[1], - (CEtors7 + CEconj4)*p_ijk->dcos_di[2] ); */ - - - /* fprintf( out_control->etor, - "%12.8f%12.8f%12.8f\n%12.8f%12.8f%12.8f\n%12.8f%12.8f%12.8f\n", - (CEtors8 + CEconj5)*p_jkl->dcos_di[0], - (CEtors8 + CEconj5)*p_jkl->dcos_di[1], - (CEtors8 + CEconj5)*p_jkl->dcos_di[2], - (CEtors8 + CEconj5)*p_jkl->dcos_dj[0], - (CEtors8 + CEconj5)*p_jkl->dcos_dj[1], - (CEtors8 + CEconj5)*p_jkl->dcos_dj[2], - (CEtors8 + CEconj5)*p_jkl->dcos_dk[0], - (CEtors8 + CEconj5)*p_jkl->dcos_dk[1], - (CEtors8 + CEconj5)*p_jkl->dcos_dk[2] ); */ - - fprintf( out_control->etor, - "%12.8f%12.8f%12.8f\n%12.8f%12.8f%12.8f\n%12.8f%12.8f%12.8f\n%12.8f%12.8f%12.8f\n", - dcos_omega_di[0], dcos_omega_di[1], dcos_omega_di[2], - dcos_omega_dj[0], dcos_omega_dj[1], dcos_omega_dj[2], - dcos_omega_dk[0], dcos_omega_dk[1], dcos_omega_dk[2], - dcos_omega_dl[0], dcos_omega_dl[1], dcos_omega_dl[2] ); + /*fprintf( out_control->etor, + //"%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f\n", + //r_ij, r_jk, r_kl, + "%12.8f%12.8f%12.8f%12.8f\n", + cos_ijk, cos_jkl, sin_ijk, sin_jkl );*/ + // fprintf( out_control->etor, "%12.8f\n", dfn11 ); + fprintf( out_control->etor, "%12.8f%12.8f%12.8f\n", + fn10, cos_omega, CV ); + + fprintf( out_control->etor, + "%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f\n", + CEtors2, CEtors3, CEtors4, CEtors5, + CEtors6, CEtors7, CEtors8, CEtors9 ); + + /* fprintf( out_control->etor, + "%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f\n", + htra, htrb, htrc, hthd, hthe, hnra, hnrc, hnhd, hnhe ); */ + + fprintf( out_control->etor, + "%12.8f%12.8f%12.8f%12.8f%12.8f%12.8f\n", + CEconj1, CEconj2, CEconj3, CEconj4, CEconj5, CEconj6 ); + /* fprintf(out_control->etor,"%23.15e%23.15e%23.15e%23.15e\n", + fbp->V1, fbp->V2, fbp->V3, fbp->p_tor1 );*/ + + fprintf( out_control->etor, + //"%6d%6d%6d%6d%23.15e%23.15e%23.15e%23.15e\n", + "%6d%6d%6d%6d%12.8f%12.8f\n", + workspace->orig_id[i], workspace->orig_id[j], + workspace->orig_id[k], workspace->orig_id[l], + e_tor, e_con ); + //RAD2DEG(omega), BOA_jk, e_tor, data->E_Tor ); + + fprintf( out_control->econ, + "%6d%6d%6d%6d%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e\n", + workspace->orig_id[i], workspace->orig_id[j], + workspace->orig_id[k], workspace->orig_id[l], + RAD2DEG(omega), BOA_ij, BOA_jk, BOA_kl, + e_con, data->E_Con ); + + /* fprintf( out_control->etor, + "%12.8f%12.8f%12.8f\n%12.8f%12.8f%12.8f\n%12.8f%12.8f%12.8f\n", + (CEtors7 + CEconj4)*p_ijk->dcos_dk[0], + (CEtors7 + CEconj4)*p_ijk->dcos_dk[1], + (CEtors7 + CEconj4)*p_ijk->dcos_dk[2], + (CEtors7 + CEconj4)*p_ijk->dcos_dj[0], + (CEtors7 + CEconj4)*p_ijk->dcos_dj[1], + (CEtors7 + CEconj4)*p_ijk->dcos_dj[2], + (CEtors7 + CEconj4)*p_ijk->dcos_di[0], + (CEtors7 + CEconj4)*p_ijk->dcos_di[1], + (CEtors7 + CEconj4)*p_ijk->dcos_di[2] ); */ + + + /* fprintf( out_control->etor, + "%12.8f%12.8f%12.8f\n%12.8f%12.8f%12.8f\n%12.8f%12.8f%12.8f\n", + (CEtors8 + CEconj5)*p_jkl->dcos_di[0], + (CEtors8 + CEconj5)*p_jkl->dcos_di[1], + (CEtors8 + CEconj5)*p_jkl->dcos_di[2], + (CEtors8 + CEconj5)*p_jkl->dcos_dj[0], + (CEtors8 + CEconj5)*p_jkl->dcos_dj[1], + (CEtors8 + CEconj5)*p_jkl->dcos_dj[2], + (CEtors8 + CEconj5)*p_jkl->dcos_dk[0], + (CEtors8 + CEconj5)*p_jkl->dcos_dk[1], + (CEtors8 + CEconj5)*p_jkl->dcos_dk[2] ); */ + + fprintf( out_control->etor, + "%12.8f%12.8f%12.8f\n%12.8f%12.8f%12.8f\n%12.8f%12.8f%12.8f\n%12.8f%12.8f%12.8f\n", + dcos_omega_di[0], dcos_omega_di[1], dcos_omega_di[2], + dcos_omega_dj[0], dcos_omega_dj[1], dcos_omega_dj[2], + dcos_omega_dk[0], dcos_omega_dk[1], dcos_omega_dk[2], + dcos_omega_dl[0], dcos_omega_dl[1], dcos_omega_dl[2] ); #endif #ifdef TEST_FORCES - /* Torsion Forces */ - Add_dBOpinpi2(system, lists, j, pk, CEtors2, 0., - workspace->f_tor, workspace->f_tor); - Add_dDelta( system, lists, j, CEtors3, workspace->f_tor ); - Add_dDelta( system, lists, k, CEtors3, workspace->f_tor ); - Add_dBO( system, lists, j, pij, CEtors4, workspace->f_tor ); - Add_dBO( system, lists, j, pk, CEtors5, workspace->f_tor ); - Add_dBO( system, lists, k, plk, CEtors6, workspace->f_tor ); - - rvec_ScaledAdd(workspace->f_tor[i], CEtors7, p_ijk->dcos_dk); - rvec_ScaledAdd(workspace->f_tor[j], CEtors7, p_ijk->dcos_dj); - rvec_ScaledAdd(workspace->f_tor[k], CEtors7, p_ijk->dcos_di); - - rvec_ScaledAdd(workspace->f_tor[j], CEtors8, p_jkl->dcos_di); - rvec_ScaledAdd(workspace->f_tor[k], CEtors8, p_jkl->dcos_dj); - rvec_ScaledAdd(workspace->f_tor[l], CEtors8, p_jkl->dcos_dk); - - rvec_ScaledAdd( workspace->f_tor[i], CEtors9, dcos_omega_di ); - rvec_ScaledAdd( workspace->f_tor[j], CEtors9, dcos_omega_dj ); - rvec_ScaledAdd( workspace->f_tor[k], CEtors9, dcos_omega_dk ); - rvec_ScaledAdd( workspace->f_tor[l], CEtors9, dcos_omega_dl ); - - /* Conjugation Forces */ - Add_dBO( system, lists, j, pij, CEconj1, workspace->f_con ); - Add_dBO( system, lists, j, pk, CEconj2, workspace->f_con ); - Add_dBO( system, lists, k, plk, CEconj3, workspace->f_con ); - - rvec_ScaledAdd(workspace->f_con[i], CEconj4, p_ijk->dcos_dk); - rvec_ScaledAdd(workspace->f_con[j], CEconj4, p_ijk->dcos_dj); - rvec_ScaledAdd(workspace->f_con[k], CEconj4, p_ijk->dcos_di); - - rvec_ScaledAdd(workspace->f_con[j], CEconj5, p_jkl->dcos_di); - rvec_ScaledAdd(workspace->f_con[k], CEconj5, p_jkl->dcos_dj); - rvec_ScaledAdd(workspace->f_con[l], CEconj5, p_jkl->dcos_dk); - - rvec_ScaledAdd( workspace->f_con[i], CEconj6, dcos_omega_di ); - rvec_ScaledAdd( workspace->f_con[j], CEconj6, dcos_omega_dj ); - rvec_ScaledAdd( workspace->f_con[k], CEconj6, dcos_omega_dk ); - rvec_ScaledAdd( workspace->f_con[l], CEconj6, dcos_omega_dl ); + /* Torsion Forces */ + Add_dBOpinpi2(system, lists, j, pk, CEtors2, 0., + workspace->f_tor, workspace->f_tor); + Add_dDelta( system, lists, j, CEtors3, workspace->f_tor ); + Add_dDelta( system, lists, k, CEtors3, workspace->f_tor ); + Add_dBO( system, lists, j, pij, CEtors4, workspace->f_tor ); + Add_dBO( system, lists, j, pk, CEtors5, workspace->f_tor ); + Add_dBO( system, lists, k, plk, CEtors6, workspace->f_tor ); + + rvec_ScaledAdd(workspace->f_tor[i], CEtors7, p_ijk->dcos_dk); + rvec_ScaledAdd(workspace->f_tor[j], CEtors7, p_ijk->dcos_dj); + rvec_ScaledAdd(workspace->f_tor[k], CEtors7, p_ijk->dcos_di); + + rvec_ScaledAdd(workspace->f_tor[j], CEtors8, p_jkl->dcos_di); + rvec_ScaledAdd(workspace->f_tor[k], CEtors8, p_jkl->dcos_dj); + rvec_ScaledAdd(workspace->f_tor[l], CEtors8, p_jkl->dcos_dk); + + rvec_ScaledAdd( workspace->f_tor[i], CEtors9, dcos_omega_di ); + rvec_ScaledAdd( workspace->f_tor[j], CEtors9, dcos_omega_dj ); + rvec_ScaledAdd( workspace->f_tor[k], CEtors9, dcos_omega_dk ); + rvec_ScaledAdd( workspace->f_tor[l], CEtors9, dcos_omega_dl ); + + /* Conjugation Forces */ + Add_dBO( system, lists, j, pij, CEconj1, workspace->f_con ); + Add_dBO( system, lists, j, pk, CEconj2, workspace->f_con ); + Add_dBO( system, lists, k, plk, CEconj3, workspace->f_con ); + + rvec_ScaledAdd(workspace->f_con[i], CEconj4, p_ijk->dcos_dk); + rvec_ScaledAdd(workspace->f_con[j], CEconj4, p_ijk->dcos_dj); + rvec_ScaledAdd(workspace->f_con[k], CEconj4, p_ijk->dcos_di); + + rvec_ScaledAdd(workspace->f_con[j], CEconj5, p_jkl->dcos_di); + rvec_ScaledAdd(workspace->f_con[k], CEconj5, p_jkl->dcos_dj); + rvec_ScaledAdd(workspace->f_con[l], CEconj5, p_jkl->dcos_dk); + + rvec_ScaledAdd( workspace->f_con[i], CEconj6, dcos_omega_di ); + rvec_ScaledAdd( workspace->f_con[j], CEconj6, dcos_omega_dj ); + rvec_ScaledAdd( workspace->f_con[k], CEconj6, dcos_omega_dk ); + rvec_ScaledAdd( workspace->f_con[l], CEconj6, dcos_omega_dl ); #endif - } // pl check ends - } // pl loop ends - } // pi check ends - } // pi loop ends - } // k-j neighbor check ends - } // j<k && j-k neighbor check ends - } // pk loop ends - } // j loop - - /* fprintf( stderr, "4body: ext_press (%23.15e %23.15e %23.15e)\n", - data->ext_press[0], data->ext_press[1], data->ext_press[2] );*/ - + } // pl check ends + } // pl loop ends + } // pi check ends + } // pi loop ends + } // k-j neighbor check ends + } // j<k && j-k neighbor check ends + } // pk loop ends + } // j loop + + /* fprintf( stderr, "4body: ext_press (%23.15e %23.15e %23.15e)\n", + data->ext_press[0], data->ext_press[1], data->ext_press[2] );*/ + #ifdef TEST_FORCES - fprintf( stderr, "Number of torsion angles: %d\n", num_frb_intrs ); - fprintf( stderr, "Torsion Energy: %g\t Conjugation Energy: %g\n", - data->E_Tor, data->E_Con ); + fprintf( stderr, "Number of torsion angles: %d\n", num_frb_intrs ); + fprintf( stderr, "Torsion Energy: %g\t Conjugation Energy: %g\n", + data->E_Tor, data->E_Con ); #endif } diff --git a/puremd_rc_1003/sPuReMD/four_body_interactions.h b/puremd_rc_1003/sPuReMD/four_body_interactions.h index d633396b..37136cd2 100644 --- a/puremd_rc_1003/sPuReMD/four_body_interactions.h +++ b/puremd_rc_1003/sPuReMD/four_body_interactions.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -25,6 +25,6 @@ #include "mytypes.h" void Four_Body_Interactions( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); + static_storage*, list**, output_controls* ); #endif diff --git a/puremd_rc_1003/sPuReMD/grid.c b/puremd_rc_1003/sPuReMD/grid.c index 407b8b96..20c87c12 100644 --- a/puremd_rc_1003/sPuReMD/grid.c +++ b/puremd_rc_1003/sPuReMD/grid.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -26,501 +26,532 @@ int Estimate_GCell_Population( reax_system* system ) { - int i, j, k, l; - int max_atoms; - grid *g; - - g = &( system->g ); - Reset_Grid( g ); - - 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]); - g->top[i][j][k]++; - // fprintf( stderr, "\tatom%-6d (%8.3f%8.3f%8.3f) --> (%3d%3d%3d)\n", - // l, system->atoms[l].x[0], system->atoms[l].x[1], system->atoms[l].x[2], - // i, j, k ); - } - - max_atoms = 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++ ) - if( max_atoms < g->top[i][j][k] ) - max_atoms = g->top[i][j][k]; - - return MAX(max_atoms*SAFE_ZONE, MIN_GCELL_POPL); + int i, j, k, l; + int max_atoms; + grid *g; + + g = &( system->g ); + Reset_Grid( g ); + + 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]); + g->top[i][j][k]++; + // fprintf( stderr, "\tatom%-6d (%8.3f%8.3f%8.3f) --> (%3d%3d%3d)\n", + // l, system->atoms[l].x[0], system->atoms[l].x[1], system->atoms[l].x[2], + // i, j, k ); + } + + max_atoms = 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++ ) + if ( max_atoms < g->top[i][j][k] ) + max_atoms = g->top[i][j][k]; + + return MAX(max_atoms * SAFE_ZONE, MIN_GCELL_POPL); } void Allocate_Space_for_Grid( reax_system *system ) { - int i, j, k, l; - 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****) calloc( g->ncell[0], sizeof( int*** )); - g->top = (int***) calloc( g->ncell[0], sizeof( int** )); - g->mark = (int***) calloc( g->ncell[0], sizeof( int** )); - g->start = (int***) calloc( g->ncell[0], sizeof( int** )); - g->end = (int***) calloc( g->ncell[0], sizeof( int** )); - g->nbrs = (ivec****) calloc( g->ncell[0], sizeof( ivec*** )); - g->nbrs_cp = (rvec****) calloc( g->ncell[0], sizeof( rvec*** )); - - for( i = 0; i < g->ncell[0]; i++ ) { - g->atoms[i] = (int***) calloc( g->ncell[1], sizeof( int** )); - g->top [i] = (int**) calloc( g->ncell[1], sizeof( int* )); - g->mark[i] = (int**) calloc( g->ncell[1], sizeof( int* )); - g->start[i] = (int**) calloc( g->ncell[1], sizeof( int* )); - g->end[i] = (int**) calloc( g->ncell[1], sizeof( int* )); - g->nbrs[i] = (ivec***) calloc( g->ncell[1], sizeof( ivec** )); - g->nbrs_cp[i] = (rvec***) calloc( g->ncell[1], sizeof( rvec** )); - - for( j = 0; j < g->ncell[1]; j++ ) { - g->atoms[i][j] = (int**) calloc( g->ncell[2], sizeof( int* )); - g->top[i][j] = (int*) calloc( g->ncell[2], sizeof( int )); - g->mark[i][j] = (int*) calloc( g->ncell[2], sizeof( int )); - g->start[i][j] = (int*) calloc( g->ncell[2], sizeof( int )); - g->end[i][j] = (int*) calloc( g->ncell[2], sizeof( int )); - g->nbrs[i][j] = (ivec**) calloc( g->ncell[2], sizeof( ivec* )); - g->nbrs_cp[i][j] = (rvec**) calloc( g->ncell[2], sizeof( rvec* )); - - for( k = 0; k < g->ncell[2]; k++ ) { - g->top[i][j][k] = 0; - g->mark[i][j][k] = 0; - g->start[i][j][k] = 0; - g->end[i][j][k] = 0; - g->nbrs[i][j][k] = (ivec*) calloc( g->max_nbrs, sizeof( ivec ) ); - g->nbrs_cp[i][j][k] = (rvec*) calloc( g->max_nbrs, sizeof( rvec ) ); - - 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; - - g->nbrs_cp[i][j][k][l][0] = -1; - g->nbrs_cp[i][j][k][l][1] = -1; - g->nbrs_cp[i][j][k][l][2] = -1; - } - } + int i, j, k, l; + 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****) calloc( g->ncell[0], sizeof( int*** )); + g->top = (int***) calloc( g->ncell[0], sizeof( int** )); + g->mark = (int***) calloc( g->ncell[0], sizeof( int** )); + g->start = (int***) calloc( g->ncell[0], sizeof( int** )); + g->end = (int***) calloc( g->ncell[0], sizeof( int** )); + g->nbrs = (ivec****) calloc( g->ncell[0], sizeof( ivec*** )); + g->nbrs_cp = (rvec****) calloc( g->ncell[0], sizeof( rvec*** )); + + for ( i = 0; i < g->ncell[0]; i++ ) + { + g->atoms[i] = (int***) calloc( g->ncell[1], sizeof( int** )); + g->top [i] = (int**) calloc( g->ncell[1], sizeof( int* )); + g->mark[i] = (int**) calloc( g->ncell[1], sizeof( int* )); + g->start[i] = (int**) calloc( g->ncell[1], sizeof( int* )); + g->end[i] = (int**) calloc( g->ncell[1], sizeof( int* )); + g->nbrs[i] = (ivec***) calloc( g->ncell[1], sizeof( ivec** )); + g->nbrs_cp[i] = (rvec***) calloc( g->ncell[1], sizeof( rvec** )); + + for ( j = 0; j < g->ncell[1]; j++ ) + { + g->atoms[i][j] = (int**) calloc( g->ncell[2], sizeof( int* )); + g->top[i][j] = (int*) calloc( g->ncell[2], sizeof( int )); + g->mark[i][j] = (int*) calloc( g->ncell[2], sizeof( int )); + g->start[i][j] = (int*) calloc( g->ncell[2], sizeof( int )); + g->end[i][j] = (int*) calloc( g->ncell[2], sizeof( int )); + g->nbrs[i][j] = (ivec**) calloc( g->ncell[2], sizeof( ivec* )); + g->nbrs_cp[i][j] = (rvec**) calloc( g->ncell[2], sizeof( rvec* )); + + for ( k = 0; k < g->ncell[2]; k++ ) + { + g->top[i][j][k] = 0; + g->mark[i][j][k] = 0; + g->start[i][j][k] = 0; + g->end[i][j][k] = 0; + g->nbrs[i][j][k] = (ivec*) calloc( g->max_nbrs, sizeof( ivec ) ); + g->nbrs_cp[i][j][k] = (rvec*) calloc( g->max_nbrs, sizeof( rvec ) ); + + 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; + + g->nbrs_cp[i][j][k][l][0] = -1; + g->nbrs_cp[i][j][k][l][1] = -1; + g->nbrs_cp[i][j][k][l][2] = -1; + } + } + } } - } - g->max_atoms = Estimate_GCell_Population( system ); - 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*) calloc( g->max_atoms, sizeof(int) ); + g->max_atoms = Estimate_GCell_Population( system ); + 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*) calloc( g->max_atoms, sizeof(int) ); } void Deallocate_Grid_Space( grid *g ) { - int i, j, k; - - /* deallocate the old grid */ - for( i = 0; i < g->ncell[0]; i++ ) { - for( j = 0; j < g->ncell[1]; j++ ) { - for( k = 0; k < g->ncell[2]; k++ ){ - free( g->atoms[i][j][k] ); - free( g->nbrs[i][j][k] ); - free( g->nbrs_cp[i][j][k] ); - } - - free( g->atoms[i][j] ); - free( g->top[i][j] ); - free( g->mark[i][j] ); - free( g->nbrs[i][j] ); - free( g->nbrs_cp[i][j] ); + int i, j, k; + + /* deallocate the old grid */ + for ( i = 0; i < g->ncell[0]; i++ ) + { + for ( j = 0; j < g->ncell[1]; j++ ) + { + for ( k = 0; k < g->ncell[2]; k++ ) + { + free( g->atoms[i][j][k] ); + free( g->nbrs[i][j][k] ); + free( g->nbrs_cp[i][j][k] ); + } + + free( g->atoms[i][j] ); + free( g->top[i][j] ); + free( g->mark[i][j] ); + free( g->nbrs[i][j] ); + free( g->nbrs_cp[i][j] ); + } + + free( g->atoms[i] ); + free( g->top[i] ); + free( g->mark[i] ); + free( g->nbrs[i] ); + free( g->nbrs_cp[i] ); } - - free( g->atoms[i] ); - free( g->top[i] ); - free( g->mark[i] ); - free( g->nbrs[i] ); - free( g->nbrs_cp[i] ); - } - - free( g->atoms ); - free( g->top ); - free( g->mark ); - free( g->nbrs ); - free( g->nbrs_cp ); + + free( g->atoms ); + free( g->top ); + free( g->mark ); + free( g->nbrs ); + free( g->nbrs_cp ); } int Shift(int p, int dp, int dim, grid *g ) { - int dim_len = 0; - int newp = p + dp; - - switch( dim ) { - case 0: dim_len = g->ncell[0]; - break; - case 1: dim_len = g->ncell[1]; - break; - case 2: dim_len = g->ncell[2]; - } - - while( newp < 0 ) newp = newp + dim_len; - while( newp >= dim_len ) newp = newp - dim_len; - return newp; + int dim_len = 0; + int newp = p + dp; + + switch ( dim ) + { + case 0: + dim_len = g->ncell[0]; + break; + case 1: + dim_len = g->ncell[1]; + break; + case 2: + dim_len = g->ncell[2]; + } + + while ( newp < 0 ) newp = newp + dim_len; + while ( newp >= dim_len ) newp = newp - dim_len; + return newp; } /* finds the closest point between two grid cells denoted by c1 and c2. periodic boundary conditions are taken into consideration as well. */ -void Find_Closest_Point( grid *g, int c1x, int c1y, int c1z, - int c2x, int c2y, int c2z, rvec closest_point ) +void Find_Closest_Point( grid *g, int c1x, int c1y, int c1z, + int c2x, int c2y, int c2z, rvec closest_point ) { - int i, d; - ivec c1 = { c1x, c1y, c1z }; - ivec c2 = { c2x, c2y, c2z }; - - for( i = 0; i < 3; i++ ) { - if( g->ncell[i] < 5 ) { - closest_point[i] = NEG_INF - 1.; - continue; - } - - d = c2[i] - c1[i]; - if( abs(d) <= g->ncell[i] / 2 ) { - if( d > 0 ) - closest_point[i] = c2[i] * g->len[i]; - else if ( d == 0 ) - closest_point[i] = NEG_INF - 1.; - else - closest_point[i] = ( c2[i] + 1 ) * g->len[i]; + int i, d; + ivec c1 = { c1x, c1y, c1z }; + ivec c2 = { c2x, c2y, c2z }; + + for ( i = 0; i < 3; i++ ) + { + if ( g->ncell[i] < 5 ) + { + closest_point[i] = NEG_INF - 1.; + continue; + } + + d = c2[i] - c1[i]; + if ( abs(d) <= g->ncell[i] / 2 ) + { + if ( d > 0 ) + closest_point[i] = c2[i] * g->len[i]; + else if ( d == 0 ) + closest_point[i] = NEG_INF - 1.; + else + closest_point[i] = ( c2[i] + 1 ) * g->len[i]; + } + else + { + if ( d > 0 ) + closest_point[i] = ( c2[i] - g->ncell[i] + 1 ) * g->len[i]; + else + closest_point[i] = ( c2[i] + g->ncell[i] ) * g->len[i]; + } } - else { - if( d > 0 ) - closest_point[i] = ( c2[i] - g->ncell[i] + 1 ) * g->len[i]; - else - closest_point[i] = ( c2[i] + g->ncell[i] ) * g->len[i]; - } - } } void Find_Neighbor_GridCells( grid *g ) { - int i, j, k; - int di, dj, dk; - int x, y, z; - int stack_top; - ivec *nbrs_stack; - rvec *cp_stack; - - /* pick up a cell in the grid */ - for( i = 0; i < g->ncell[0]; i++ ) - for( j = 0; j < g->ncell[1]; j++ ) - for( k = 0; k < g->ncell[2]; k++ ) { - nbrs_stack = g->nbrs[i][j][k]; - cp_stack = g->nbrs_cp[i][j][k]; - stack_top = 0; - //fprintf( stderr, "grid1: %d %d %d\n", i, j, k ); - - /* choose an unmarked neighbor cell*/ - for( di = -g->spread[0]; di <= g->spread[0]; di++ ) { - x = Shift( i, di, 0, g ); - - for( dj = -g->spread[1]; dj <= g->spread[1]; dj++ ) { - y = Shift( j, dj, 1, g ); - - for( dk = -g->spread[2]; dk <= g->spread[2]; dk++ ) { - z = Shift( k, dk, 2, g ); - //fprintf( stderr, "\tgrid2: %d %d %d\n", x, y, z ); - - if( !g->mark[x][y][z] ) { - /*(di < 0 || // 9 combinations - (di == 0 && dj < 0) || // 3 combinations - (di == 0 && dj == 0 && dk < 0) ) )*/ - /* put the neighbor cell into the stack and mark it */ - nbrs_stack[stack_top][0] = x; - nbrs_stack[stack_top][1] = y; - nbrs_stack[stack_top][2] = z; - g->mark[x][y][z] = 1; - - Find_Closest_Point( g, i, j, k, x, y, z, cp_stack[stack_top] ); - //fprintf( stderr, "\tcp: %lf %lf %lf\n", - // cp_stack[stack_top][0], cp_stack[stack_top][1], - // cp_stack[stack_top][2]); - stack_top++; - } - } - } - } - - /*nbrs_stack[stack_top][0] = i; - nbrs_stack[stack_top][1] = j; - nbrs_stack[stack_top][2] = k; - Find_Closest_Point( g, i, j, k, i, j, k, cp_stack[stack_top] ); - nbrs_stack[stack_top+1][0] = -1; - nbrs_stack[stack_top+1][1] = -1; - nbrs_stack[stack_top+1][2] = -1; - Reset_Marks( g, nbrs_stack, stack_top+1 );*/ - nbrs_stack[stack_top][0] = -1; - nbrs_stack[stack_top][1] = -1; - nbrs_stack[stack_top][2] = -1; - Reset_Marks( g, nbrs_stack, stack_top ); - } + int i, j, k; + int di, dj, dk; + int x, y, z; + int stack_top; + ivec *nbrs_stack; + rvec *cp_stack; + + /* pick up a cell in the grid */ + for ( i = 0; i < g->ncell[0]; i++ ) + for ( j = 0; j < g->ncell[1]; j++ ) + for ( k = 0; k < g->ncell[2]; k++ ) + { + nbrs_stack = g->nbrs[i][j][k]; + cp_stack = g->nbrs_cp[i][j][k]; + stack_top = 0; + //fprintf( stderr, "grid1: %d %d %d\n", i, j, k ); + + /* choose an unmarked neighbor cell*/ + for ( di = -g->spread[0]; di <= g->spread[0]; di++ ) + { + x = Shift( i, di, 0, g ); + + for ( dj = -g->spread[1]; dj <= g->spread[1]; dj++ ) + { + y = Shift( j, dj, 1, g ); + + for ( dk = -g->spread[2]; dk <= g->spread[2]; dk++ ) + { + z = Shift( k, dk, 2, g ); + //fprintf( stderr, "\tgrid2: %d %d %d\n", x, y, z ); + + if ( !g->mark[x][y][z] ) + { + /*(di < 0 || // 9 combinations + (di == 0 && dj < 0) || // 3 combinations + (di == 0 && dj == 0 && dk < 0) ) )*/ + /* put the neighbor cell into the stack and mark it */ + nbrs_stack[stack_top][0] = x; + nbrs_stack[stack_top][1] = y; + nbrs_stack[stack_top][2] = z; + g->mark[x][y][z] = 1; + + Find_Closest_Point( g, i, j, k, x, y, z, cp_stack[stack_top] ); + //fprintf( stderr, "\tcp: %lf %lf %lf\n", + // cp_stack[stack_top][0], cp_stack[stack_top][1], + // cp_stack[stack_top][2]); + stack_top++; + } + } + } + } + + /*nbrs_stack[stack_top][0] = i; + nbrs_stack[stack_top][1] = j; + nbrs_stack[stack_top][2] = k; + Find_Closest_Point( g, i, j, k, i, j, k, cp_stack[stack_top] ); + nbrs_stack[stack_top+1][0] = -1; + nbrs_stack[stack_top+1][1] = -1; + nbrs_stack[stack_top+1][2] = -1; + Reset_Marks( g, nbrs_stack, stack_top+1 );*/ + nbrs_stack[stack_top][0] = -1; + nbrs_stack[stack_top][1] = -1; + nbrs_stack[stack_top][2] = -1; + Reset_Marks( g, nbrs_stack, stack_top ); + } } void Setup_Grid( reax_system* system ) { - int d; - ivec ncell; - grid *g = &( system->g ); - simulation_box *my_box = &( system->box ); + int d; + ivec ncell; + grid *g = &( system->g ); + simulation_box *my_box = &( system->box ); + + /* determine number of grid cells in each direction */ + ivec_rScale( ncell, 1. / g->cell_size, my_box->box_norms ); - /* determine number of grid cells in each direction */ - ivec_rScale( ncell, 1. / g->cell_size, my_box->box_norms ); + for ( d = 0; d < 3; ++d ) + if ( ncell[d] <= 0 ) + ncell[d] = 1; - for( d = 0; d < 3; ++d ) - if( ncell[d] <= 0 ) - ncell[d] = 1; - - /* find the number of grid cells */ - g->total = ncell[0] * ncell[1] * ncell[2]; - ivec_Copy( g->ncell, ncell ); + /* find the number of grid cells */ + g->total = ncell[0] * ncell[1] * ncell[2]; + ivec_Copy( g->ncell, ncell ); - /* compute cell lengths */ - rvec_iDivide( g->len, my_box->box_norms, g->ncell ); - rvec_Invert( g->inv_len, g->len ); + /* 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 ); - Find_Neighbor_GridCells( g ); + Allocate_Space_for_Grid( system ); + Find_Neighbor_GridCells( g ); #if defined(DEBUG_FOCUS) - fprintf( stderr, "setting up the grid: " ); - fprintf( stderr, "ncell[%d %d %d] ", g->ncell[0], g->ncell[1], g->ncell[2] ); - fprintf( stderr, "len[%5.2f %5.2f %5.2f] ", g->len[0], g->len[1], g->len[2] ); - fprintf( stderr, "g->max_atoms = %d\n", g->max_atoms ); + fprintf( stderr, "setting up the grid: " ); + fprintf( stderr, "ncell[%d %d %d] ", g->ncell[0], g->ncell[1], g->ncell[2] ); + fprintf( stderr, "len[%5.2f %5.2f %5.2f] ", g->len[0], g->len[1], g->len[2] ); + fprintf( stderr, "g->max_atoms = %d\n", g->max_atoms ); #endif } void Update_Grid( reax_system* system ) { - int d, i, j, k, x, y, z, itr; - ivec ncell; - ivec *nbrs; - rvec *nbrs_cp; - grid *g = &( system->g ); - simulation_box *my_box = &( system->box ); - - /* determine number of grid cells in each direction */ - ivec_rScale( ncell, 1. / g->cell_size, my_box->box_norms ); - - for( d = 0; d < 3; ++d ) - if( ncell[d] == 0 ) - ncell[d] = 1; - - if( ivec_isEqual( ncell, g->ncell ) ) {/* ncell are unchanged */ - /* update cell lengths */ - rvec_iDivide( g->len, my_box->box_norms, g->ncell ); - rvec_Invert( g->inv_len, g->len ); - - /* update closest point distances between gcells */ - for( i = 0; i < g->ncell[0]; i++ ) - for( j = 0; j < g->ncell[1]; j++ ) - for( k = 0; k < g->ncell[2]; k++ ) { - nbrs = g->nbrs[i][j][k]; - nbrs_cp = g->nbrs_cp[i][j][k]; - //fprintf( stderr, "gridcell %d %d %d\n", i, j, k ); - - itr = 0; - while( nbrs[itr][0] >= 0 ){ - x = nbrs[itr][0]; - y = nbrs[itr][1]; - z = nbrs[itr][2]; - - Find_Closest_Point( g, i, j, k, x, y, z, nbrs_cp[itr] ); - ++itr; - } - } - } - else{ /* at least one of ncell has changed */ - 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 ); - Find_Neighbor_GridCells( g ); + int d, i, j, k, x, y, z, itr; + ivec ncell; + ivec *nbrs; + rvec *nbrs_cp; + grid *g = &( system->g ); + simulation_box *my_box = &( system->box ); + + /* determine number of grid cells in each direction */ + ivec_rScale( ncell, 1. / g->cell_size, my_box->box_norms ); + + for ( d = 0; d < 3; ++d ) + if ( ncell[d] == 0 ) + ncell[d] = 1; + + if ( ivec_isEqual( ncell, g->ncell ) ) /* ncell are unchanged */ + { + /* update cell lengths */ + rvec_iDivide( g->len, my_box->box_norms, g->ncell ); + rvec_Invert( g->inv_len, g->len ); + + /* update closest point distances between gcells */ + for ( i = 0; i < g->ncell[0]; i++ ) + for ( j = 0; j < g->ncell[1]; j++ ) + for ( k = 0; k < g->ncell[2]; k++ ) + { + nbrs = g->nbrs[i][j][k]; + nbrs_cp = g->nbrs_cp[i][j][k]; + //fprintf( stderr, "gridcell %d %d %d\n", i, j, k ); + + itr = 0; + while ( nbrs[itr][0] >= 0 ) + { + x = nbrs[itr][0]; + y = nbrs[itr][1]; + z = nbrs[itr][2]; + + Find_Closest_Point( g, i, j, k, x, y, z, nbrs_cp[itr] ); + ++itr; + } + } + } + else /* at least one of ncell has changed */ + { + 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 ); + Find_Neighbor_GridCells( g ); #if defined(DEBUG_FOCUS) - fprintf( stderr, "updated grid: " ); - fprintf( stderr, "ncell[%d %d %d] ", - g->ncell[0], g->ncell[1], g->ncell[2] ); - fprintf( stderr, "len[%5.2f %5.2f %5.2f] ", - g->len[0], g->len[1], g->len[2] ); - fprintf( stderr, "g->max_atoms = %d\n", g->max_atoms ); + fprintf( stderr, "updated grid: " ); + fprintf( stderr, "ncell[%d %d %d] ", + g->ncell[0], g->ncell[1], g->ncell[2] ); + fprintf( stderr, "len[%5.2f %5.2f %5.2f] ", + g->len[0], g->len[1], g->len[2] ); + fprintf( stderr, "g->max_atoms = %d\n", g->max_atoms ); #endif - } + } } void Bin_Atoms( reax_system* system, static_storage *workspace ) { - int i, j, k, l; - int max_atoms; - grid *g = &( system->g ); - - Reset_Grid( g ); - 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]); - g->atoms[i][j][k][g->top[i][j][k]] = l; - g->top[i][j][k]++; - // fprintf( stderr, "\tatom%-6d (%8.3f%8.3f%8.3f) --> (%3d%3d%3d)\n", - // l, system->atoms[l].x[0], system->atoms[l].x[1], system->atoms[l].x[2], - // i, j, k ); - } - - max_atoms = 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++ ) - if( max_atoms < g->top[i][j][k] ) - max_atoms = g->top[i][j][k]; - - /* check if current gcell->max_atoms is safe */ - if( max_atoms >= g->max_atoms * SAFE_ZONE ) - workspace->realloc.gcell_atoms = MAX(max_atoms*SAFE_ZONE,MIN_GCELL_POPL); + int i, j, k, l; + int max_atoms; + grid *g = &( system->g ); + + Reset_Grid( g ); + 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]); + g->atoms[i][j][k][g->top[i][j][k]] = l; + g->top[i][j][k]++; + // fprintf( stderr, "\tatom%-6d (%8.3f%8.3f%8.3f) --> (%3d%3d%3d)\n", + // l, system->atoms[l].x[0], system->atoms[l].x[1], system->atoms[l].x[2], + // i, j, k ); + } + + max_atoms = 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++ ) + if ( max_atoms < g->top[i][j][k] ) + max_atoms = g->top[i][j][k]; + + /* check if current gcell->max_atoms is safe */ + if ( max_atoms >= g->max_atoms * SAFE_ZONE ) + workspace->realloc.gcell_atoms = MAX(max_atoms * SAFE_ZONE, MIN_GCELL_POPL); } inline void reax_atom_Copy( reax_atom *dest, reax_atom *src ) { - dest->type = src->type; - rvec_Copy( dest->x, src->x ); - rvec_Copy( dest->v, src->v ); - strcpy( dest->name, src->name ); + dest->type = src->type; + rvec_Copy( dest->x, src->x ); + rvec_Copy( dest->v, src->v ); + strcpy( dest->name, src->name ); } -void Copy_Storage( reax_system *system, static_storage *workspace, - int top, int old_id, int old_type, - int *num_H, real **v, real **s, real **t, - int *orig_id, rvec *f_old ) +void Copy_Storage( reax_system *system, static_storage *workspace, + int top, int old_id, int old_type, + int *num_H, real **v, real **s, real **t, + int *orig_id, rvec *f_old ) { - int i; - - for( i = 0; i < RESTART+1; ++i ) - v[i][top] = workspace->v[i][old_id]; - - for( i = 0; i < 3; ++i ) { - s[i][top] = workspace->s[i][old_id]; - t[i][top] = workspace->t[i][old_id]; - } - - orig_id[top] = workspace->orig_id[old_id]; - - workspace->Hdia_inv[top] = 1. / system->reaxprm.sbp[ old_type ].eta; - workspace->b_s[top] = -system->reaxprm.sbp[ old_type ].chi; - workspace->b_t[top] = -1.0; - - if( system->reaxprm.sbp[ old_type ].p_hbond == 1 ) // H atom - workspace->hbond_index[top] = (*num_H)++; - else workspace->hbond_index[top] = -1; - - rvec_Copy( f_old[top], workspace->f_old[old_id] ); + int i; + + for ( i = 0; i < RESTART + 1; ++i ) + v[i][top] = workspace->v[i][old_id]; + + for ( i = 0; i < 3; ++i ) + { + s[i][top] = workspace->s[i][old_id]; + t[i][top] = workspace->t[i][old_id]; + } + + orig_id[top] = workspace->orig_id[old_id]; + + workspace->Hdia_inv[top] = 1. / system->reaxprm.sbp[ old_type ].eta; + workspace->b_s[top] = -system->reaxprm.sbp[ old_type ].chi; + workspace->b_t[top] = -1.0; + + if ( system->reaxprm.sbp[ old_type ].p_hbond == 1 ) // H atom + workspace->hbond_index[top] = (*num_H)++; + else workspace->hbond_index[top] = -1; + + rvec_Copy( f_old[top], workspace->f_old[old_id] ); } void Free_Storage( static_storage *workspace ) { - int i; + int i; - for( i = 0; i < RESTART+1; ++i ) - free( workspace->v[i] ); - free( workspace->v ); + for ( i = 0; i < RESTART + 1; ++i ) + free( workspace->v[i] ); + free( workspace->v ); - for( i = 0; i < 3; ++i ) { - free( workspace->s[i] ); - free( workspace->t[i] ); - } - free( workspace->s ); - free( workspace->t ); + for ( i = 0; i < 3; ++i ) + { + free( workspace->s[i] ); + free( workspace->t[i] ); + } + free( workspace->s ); + free( workspace->t ); - free( workspace->orig_id ); + free( workspace->orig_id ); } -void Assign_New_Storage( static_storage *workspace, - real **v, real **s, real **t, - int *orig_id, rvec *f_old ) +void Assign_New_Storage( static_storage *workspace, + real **v, real **s, real **t, + int *orig_id, rvec *f_old ) { - workspace->v = v; + workspace->v = v; + + workspace->s = s; + workspace->t = t; - workspace->s = s; - workspace->t = t; - - workspace->orig_id = orig_id; + workspace->orig_id = orig_id; - workspace->f_old = f_old; + workspace->f_old = f_old; } void Cluster_Atoms( reax_system *system, static_storage *workspace ) { - int i, j, k, l, top, old_id, num_H = 0; - reax_atom *old_atom; - grid *g = &( system->g ); - reax_atom *new_atoms = (reax_atom*) calloc( system->N, sizeof(reax_atom) ); - int *orig_id = (int *) calloc( system->N, sizeof( int ) ); - real **v; - real **s, **t; - rvec *f_old = (rvec*) calloc( system->N, sizeof(rvec) ); - - s = (real**) calloc( 3, sizeof( real* ) ); - t = (real**) calloc( 3, sizeof( real* ) ); - for( i = 0; i < 3; ++i ) { - s[i] = (real *) calloc( system->N, sizeof( real ) ); - t[i] = (real *) calloc( system->N, sizeof( real ) ); - } - - v = (real**) calloc( RESTART+1, sizeof( real* ) ); - for( i = 0; i < RESTART+1; ++i ) - v[i] = (real *) calloc( system->N, sizeof( real ) ); - - - top = 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] = top; - - for( l = 0; l < g->top[i][j][k]; ++l ) { - old_id = g->atoms[i][j][k][l]; - old_atom = &( system->atoms[old_id] ); - // fprintf( stderr, "%d <-- %d\n", top, old_id ); - - reax_atom_Copy( &(new_atoms[top]), old_atom ); - Copy_Storage( system, workspace, top, old_id, old_atom->type, - &num_H, v, s, t, orig_id, f_old ); - ++top; - } - - g->end[i][j][k] = top; - } - - - free( system->atoms ); - Free_Storage( workspace ); - - system->atoms = new_atoms; - Assign_New_Storage( workspace, v, s, t, orig_id, f_old ); + int i, j, k, l, top, old_id, num_H = 0; + reax_atom *old_atom; + grid *g = &( system->g ); + reax_atom *new_atoms = (reax_atom*) calloc( system->N, sizeof(reax_atom) ); + int *orig_id = (int *) calloc( system->N, sizeof( int ) ); + real **v; + real **s, **t; + rvec *f_old = (rvec*) calloc( system->N, sizeof(rvec) ); + + s = (real**) calloc( 3, sizeof( real* ) ); + t = (real**) calloc( 3, sizeof( real* ) ); + for ( i = 0; i < 3; ++i ) + { + s[i] = (real *) calloc( system->N, sizeof( real ) ); + t[i] = (real *) calloc( system->N, sizeof( real ) ); + } + + v = (real**) calloc( RESTART + 1, sizeof( real* ) ); + for ( i = 0; i < RESTART + 1; ++i ) + v[i] = (real *) calloc( system->N, sizeof( real ) ); + + + top = 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] = top; + + for ( l = 0; l < g->top[i][j][k]; ++l ) + { + old_id = g->atoms[i][j][k][l]; + old_atom = &( system->atoms[old_id] ); + // fprintf( stderr, "%d <-- %d\n", top, old_id ); + + reax_atom_Copy( &(new_atoms[top]), old_atom ); + Copy_Storage( system, workspace, top, old_id, old_atom->type, + &num_H, v, s, t, orig_id, f_old ); + ++top; + } + + g->end[i][j][k] = top; + } + + + free( system->atoms ); + Free_Storage( workspace ); + + system->atoms = new_atoms; + Assign_New_Storage( workspace, v, s, t, orig_id, f_old ); } diff --git a/puremd_rc_1003/sPuReMD/grid.h b/puremd_rc_1003/sPuReMD/grid.h index af755efd..41d7b57e 100644 --- a/puremd_rc_1003/sPuReMD/grid.h +++ b/puremd_rc_1003/sPuReMD/grid.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ diff --git a/puremd_rc_1003/sPuReMD/init_md.c b/puremd_rc_1003/sPuReMD/init_md.c index def855fc..d6f15a1e 100644 --- a/puremd_rc_1003/sPuReMD/init_md.c +++ b/puremd_rc_1003/sPuReMD/init_md.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -38,643 +38,669 @@ void Generate_Initial_Velocities( reax_system *system, real T ) { - int i; - real scale, norm; - - - if( T <= 0.1 ) { - for (i=0; i < system->N; i++) - rvec_MakeZero( system->atoms[i].v ); + int i; + real scale, norm; + + + if ( T <= 0.1 ) + { + for (i = 0; i < system->N; i++) + rvec_MakeZero( system->atoms[i].v ); #if defined(DEBUG) - fprintf( stderr, "no random velocities...\n" ); + fprintf( stderr, "no random velocities...\n" ); #endif - } - else { - for( i = 0; i < system->N; i++ ) { - rvec_Random( system->atoms[i].v ); - - norm = rvec_Norm_Sqr( system->atoms[i].v ); - scale = SQRT( system->reaxprm.sbp[ system->atoms[i].type ].mass * - norm / (3.0 * K_B * T) ); - - rvec_Scale( system->atoms[i].v, 1.0/scale, system->atoms[i].v ); - - /*fprintf( stderr, "v = %f %f %f\n", - system->atoms[i].v[0],system->atoms[i].v[1],system->atoms[i].v[2]); - fprintf( stderr, "scale = %f\n", scale ); - fprintf( stderr, "v = %f %f %f\n", - system->atoms[i].v[0],system->atoms[i].v[1],system->atoms[i].v[2]);*/ } - } + else + { + for ( i = 0; i < system->N; i++ ) + { + rvec_Random( system->atoms[i].v ); + + norm = rvec_Norm_Sqr( system->atoms[i].v ); + scale = SQRT( system->reaxprm.sbp[ system->atoms[i].type ].mass * + norm / (3.0 * K_B * T) ); + + rvec_Scale( system->atoms[i].v, 1.0 / scale, system->atoms[i].v ); + + /*fprintf( stderr, "v = %f %f %f\n", + system->atoms[i].v[0],system->atoms[i].v[1],system->atoms[i].v[2]); + fprintf( stderr, "scale = %f\n", scale ); + fprintf( stderr, "v = %f %f %f\n", + system->atoms[i].v[0],system->atoms[i].v[1],system->atoms[i].v[2]);*/ + } + } } -void Init_System( reax_system *system, control_params *control, - simulation_data *data ) +void Init_System( reax_system *system, control_params *control, + simulation_data *data ) { - int i; - rvec dx; - - if( !control->restart ) - Reset_Atoms( system ); - - Compute_Total_Mass( system, data ); - Compute_Center_of_Mass( system, data, stderr ); - - /* reposition atoms */ - // just fit the atoms to the periodic box - if( control->reposition_atoms == 0 ) { - rvec_MakeZero( dx ); - } - // put the center of mass to the center of the box - else if( control->reposition_atoms == 1 ) { - rvec_Scale( dx, 0.5, system->box.box_norms ); - rvec_ScaledAdd( dx, -1., data->xcm ); - } - // put the center of mass to the origin - else if( control->reposition_atoms == 2 ) { - rvec_Scale( dx, -1., data->xcm ); - } - else { - fprintf( stderr, "UNKNOWN OPTION: reposition_atoms. Terminating...\n" ); - exit( UNKNOWN_OPTION ); - } - - for( i = 0; i < system->N; ++i ) { - Inc_on_T3( system->atoms[i].x, dx, &(system->box) ); - /*fprintf( stderr, "%6d%2d%8.3f%8.3f%8.3f\n", - i, system->atoms[i].type, - system->atoms[i].x[0], system->atoms[i].x[1], system->atoms[i].x[2] );*/ - } - - /* Initialize velocities so that desired init T can be attained */ - if( !control->restart || (control->restart && control->random_vel) ) - Generate_Initial_Velocities( system, control->T_init ); - - Setup_Grid( system ); + int i; + rvec dx; + + if ( !control->restart ) + Reset_Atoms( system ); + + Compute_Total_Mass( system, data ); + Compute_Center_of_Mass( system, data, stderr ); + + /* reposition atoms */ + // just fit the atoms to the periodic box + if ( control->reposition_atoms == 0 ) + { + rvec_MakeZero( dx ); + } + // put the center of mass to the center of the box + else if ( control->reposition_atoms == 1 ) + { + rvec_Scale( dx, 0.5, system->box.box_norms ); + rvec_ScaledAdd( dx, -1., data->xcm ); + } + // put the center of mass to the origin + else if ( control->reposition_atoms == 2 ) + { + rvec_Scale( dx, -1., data->xcm ); + } + else + { + fprintf( stderr, "UNKNOWN OPTION: reposition_atoms. Terminating...\n" ); + exit( UNKNOWN_OPTION ); + } + + for ( i = 0; i < system->N; ++i ) + { + Inc_on_T3( system->atoms[i].x, dx, &(system->box) ); + /*fprintf( stderr, "%6d%2d%8.3f%8.3f%8.3f\n", + i, system->atoms[i].type, + system->atoms[i].x[0], system->atoms[i].x[1], system->atoms[i].x[2] );*/ + } + + /* Initialize velocities so that desired init T can be attained */ + if ( !control->restart || (control->restart && control->random_vel) ) + Generate_Initial_Velocities( system, control->T_init ); + + Setup_Grid( system ); } -void Init_Simulation_Data( reax_system *system, control_params *control, - simulation_data *data, output_controls *out_control, - evolve_function *Evolve ) +void Init_Simulation_Data( reax_system *system, control_params *control, + simulation_data *data, output_controls *out_control, + evolve_function *Evolve ) { - - Reset_Simulation_Data( data ); - - if( !control->restart ) - data->step = data->prev_steps = 0; - - switch( control->ensemble ) { - case NVE: - data->N_f = 3 * system->N; - *Evolve = Velocity_Verlet_NVE; - break; - - - case NVT: - data->N_f = 3 * system->N + 1; - //control->Tau_T = 100 * data->N_f * K_B * control->T_final; - if( !control->restart || (control->restart && control->random_vel) ) { - data->therm.G_xi = control->Tau_T * (2.0 * data->E_Kin - - data->N_f * K_B * control->T ); - data->therm.v_xi = data->therm.G_xi * control->dt; - data->therm.v_xi_old = 0; - data->therm.xi = 0; + + Reset_Simulation_Data( data ); + + if ( !control->restart ) + data->step = data->prev_steps = 0; + + switch ( control->ensemble ) + { + case NVE: + data->N_f = 3 * system->N; + *Evolve = Velocity_Verlet_NVE; + break; + + + case NVT: + data->N_f = 3 * system->N + 1; + //control->Tau_T = 100 * data->N_f * K_B * control->T_final; + if ( !control->restart || (control->restart && control->random_vel) ) + { + data->therm.G_xi = control->Tau_T * (2.0 * data->E_Kin - + data->N_f * K_B * control->T ); + data->therm.v_xi = data->therm.G_xi * control->dt; + data->therm.v_xi_old = 0; + data->therm.xi = 0; #if defined(DEBUG_FOCUS) - fprintf( stderr, "init_md: G_xi=%f Tau_T=%f E_kin=%f N_f=%f v_xi=%f\n", - data->therm.G_xi, control->Tau_T, data->E_Kin, - data->N_f, data->therm.v_xi ); + fprintf( stderr, "init_md: G_xi=%f Tau_T=%f E_kin=%f N_f=%f v_xi=%f\n", + data->therm.G_xi, control->Tau_T, data->E_Kin, + data->N_f, data->therm.v_xi ); #endif + } + + *Evolve = Velocity_Verlet_Nose_Hoover_NVT_Klein; + break; + + + case NPT: // Anisotropic NPT + fprintf( stderr, "THIS OPTION IS NOT YET IMPLEMENTED! TERMINATING...\n" ); + exit( UNKNOWN_OPTION ); + data->N_f = 3 * system->N + 9; + if ( !control->restart ) + { + data->therm.G_xi = control->Tau_T * (2.0 * data->E_Kin - + data->N_f * K_B * control->T ); + data->therm.v_xi = data->therm.G_xi * control->dt; + data->iso_bar.eps = 0.33333 * log(system->box.volume); + //data->inv_W = 1. / (data->N_f*K_B*control->T*SQR(control->Tau_P)); + //Compute_Pressure( system, data, workspace ); + } + *Evolve = Velocity_Verlet_Berendsen_Isotropic_NPT; + break; + + + case sNPT: // Semi-Isotropic NPT + data->N_f = 3 * system->N + 4; + *Evolve = Velocity_Verlet_Berendsen_SemiIsotropic_NPT; + break; + + + case iNPT: // Isotropic NPT + data->N_f = 3 * system->N + 2; + *Evolve = Velocity_Verlet_Berendsen_Isotropic_NPT; + break; + + case bNVT: + data->N_f = 3 * system->N + 1; + *Evolve = Velocity_Verlet_Berendsen_NVT; + fprintf (stderr, " Initializing Velocity_Verlet_Berendsen_NVT .... \n"); + break; + + default: + break; } - - *Evolve = Velocity_Verlet_Nose_Hoover_NVT_Klein; - break; - - - case NPT: // Anisotropic NPT - fprintf( stderr, "THIS OPTION IS NOT YET IMPLEMENTED! TERMINATING...\n" ); - exit( UNKNOWN_OPTION ); - data->N_f = 3 * system->N + 9; - if( !control->restart ) { - data->therm.G_xi = control->Tau_T * (2.0 * data->E_Kin - - data->N_f * K_B * control->T ); - data->therm.v_xi = data->therm.G_xi * control->dt; - data->iso_bar.eps = 0.33333 * log(system->box.volume); - //data->inv_W = 1. / (data->N_f*K_B*control->T*SQR(control->Tau_P)); - //Compute_Pressure( system, data, workspace ); - } - *Evolve = Velocity_Verlet_Berendsen_Isotropic_NPT; - break; - - - case sNPT: // Semi-Isotropic NPT - data->N_f = 3 * system->N + 4; - *Evolve = Velocity_Verlet_Berendsen_SemiIsotropic_NPT; - break; - - - case iNPT: // Isotropic NPT - data->N_f = 3 * system->N + 2; - *Evolve = Velocity_Verlet_Berendsen_Isotropic_NPT; - break; - - case bNVT: - data->N_f = 3 * system->N + 1; - *Evolve = Velocity_Verlet_Berendsen_NVT; - fprintf (stderr, " Initializing Velocity_Verlet_Berendsen_NVT .... \n"); - break; - - default: - break; - } - - Compute_Kinetic_Energy( system, data ); - - /* init timing info */ - data->timing.start = Get_Time( ); - data->timing.total = data->timing.start; - data->timing.nbrs = 0; - data->timing.init_forces = 0; - data->timing.bonded = 0; - data->timing.nonb = 0; - data->timing.QEq = 0; - data->timing.matvecs = 0; + + Compute_Kinetic_Energy( system, data ); + + /* init timing info */ + data->timing.start = Get_Time( ); + data->timing.total = data->timing.start; + data->timing.nbrs = 0; + data->timing.init_forces = 0; + data->timing.bonded = 0; + data->timing.nonb = 0; + data->timing.QEq = 0; + data->timing.matvecs = 0; } -void Init_Workspace( reax_system *system, control_params *control, - static_storage *workspace ) -{ - int i; - - /* Allocate space for hydrogen bond list */ - workspace->hbond_index = (int *) malloc( system->N * sizeof( int ) ); - - /* bond order related storage */ - workspace->total_bond_order = (real *) malloc( system->N * sizeof( real ) ); - workspace->Deltap = (real *) malloc( system->N * sizeof( real ) ); - workspace->Deltap_boc = (real *) malloc( system->N * sizeof( real ) ); - workspace->dDeltap_self = (rvec *) malloc( system->N * sizeof( rvec ) ); - - workspace->Delta = (real *) malloc( system->N * sizeof( real ) ); - workspace->Delta_lp = (real *) malloc( system->N * sizeof( real ) ); - workspace->Delta_lp_temp = (real *) malloc( system->N * sizeof( real ) ); - workspace->dDelta_lp = (real *) malloc( system->N * sizeof( real ) ); - workspace->dDelta_lp_temp = (real *) malloc( system->N * sizeof( real ) ); - workspace->Delta_e = (real *) malloc( system->N * sizeof( real ) ); - workspace->Delta_boc = (real *) malloc( system->N * sizeof( real ) ); - workspace->nlp = (real *) malloc( system->N * sizeof( real ) ); - workspace->nlp_temp = (real *) malloc( system->N * sizeof( real ) ); - workspace->Clp = (real *) malloc( system->N * sizeof( real ) ); - workspace->CdDelta = (real *) malloc( system->N * sizeof( real ) ); - workspace->vlpex = (real *) malloc( system->N * sizeof( real ) ); - - /* QEq storage */ - workspace->H = NULL; - workspace->L = NULL; - workspace->U = NULL; - workspace->droptol = (real *) calloc( system->N, sizeof( real ) ); - workspace->w = (real *) calloc( system->N, sizeof( real ) ); - workspace->Hdia_inv = (real *) calloc( system->N, sizeof( real ) ); - workspace->b = (real *) calloc( system->N * 2, sizeof( real ) ); - workspace->b_s = (real *) calloc( system->N, sizeof( real ) ); - workspace->b_t = (real *) calloc( system->N, sizeof( real ) ); - workspace->b_prc = (real *) calloc( system->N * 2, sizeof( real ) ); - workspace->b_prm = (real *) calloc( system->N * 2, sizeof( real ) ); - workspace->s_t = (real *) calloc( system->N * 2, sizeof( real ) ); - workspace->s = (real**) calloc( 5, sizeof( real* ) ); - workspace->t = (real**) calloc( 5, sizeof( real* ) ); - for( i = 0; i < 5; ++i ) { - workspace->s[i] = (real *) calloc( system->N, sizeof( real ) ); - workspace->t[i] = (real *) calloc( system->N, sizeof( real ) ); - } - // workspace->s_old = (real *) calloc( system->N, sizeof( real ) ); - // workspace->t_old = (real *) calloc( system->N, sizeof( real ) ); - // workspace->s_oldest = (real *) calloc( system->N, sizeof( real ) ); - // workspace->t_oldest = (real *) calloc( system->N, sizeof( real ) ); - - for( i = 0; i < system->N; ++i ) { - workspace->Hdia_inv[i] = 1./system->reaxprm.sbp[system->atoms[i].type].eta; - workspace->b_s[i] = -system->reaxprm.sbp[ system->atoms[i].type ].chi; - workspace->b_t[i] = -1.0; - - workspace->b[i] = -system->reaxprm.sbp[ system->atoms[i].type ].chi; - workspace->b[i+system->N] = -1.0; - } - - /* GMRES storage */ - workspace->y = (real *) calloc( RESTART+1, sizeof( real ) ); - workspace->z = (real *) calloc( RESTART+1, sizeof( real ) ); - workspace->g = (real *) calloc( RESTART+1, sizeof( real ) ); - workspace->h = (real **) calloc( RESTART+1, sizeof( real*) ); - workspace->hs = (real *) calloc( RESTART+1, sizeof( real ) ); - workspace->hc = (real *) calloc( RESTART+1, sizeof( real ) ); - workspace->rn = (real **) calloc( RESTART+1, sizeof( real*) ); - workspace->v = (real **) calloc( RESTART+1, sizeof( real*) ); - - for( i = 0; i < RESTART+1; ++i ) +void Init_Workspace( reax_system *system, control_params *control, + static_storage *workspace ) +{ + int i; + + /* Allocate space for hydrogen bond list */ + workspace->hbond_index = (int *) malloc( system->N * sizeof( int ) ); + + /* bond order related storage */ + workspace->total_bond_order = (real *) malloc( system->N * sizeof( real ) ); + workspace->Deltap = (real *) malloc( system->N * sizeof( real ) ); + workspace->Deltap_boc = (real *) malloc( system->N * sizeof( real ) ); + workspace->dDeltap_self = (rvec *) malloc( system->N * sizeof( rvec ) ); + + workspace->Delta = (real *) malloc( system->N * sizeof( real ) ); + workspace->Delta_lp = (real *) malloc( system->N * sizeof( real ) ); + workspace->Delta_lp_temp = (real *) malloc( system->N * sizeof( real ) ); + workspace->dDelta_lp = (real *) malloc( system->N * sizeof( real ) ); + workspace->dDelta_lp_temp = (real *) malloc( system->N * sizeof( real ) ); + workspace->Delta_e = (real *) malloc( system->N * sizeof( real ) ); + workspace->Delta_boc = (real *) malloc( system->N * sizeof( real ) ); + workspace->nlp = (real *) malloc( system->N * sizeof( real ) ); + workspace->nlp_temp = (real *) malloc( system->N * sizeof( real ) ); + workspace->Clp = (real *) malloc( system->N * sizeof( real ) ); + workspace->CdDelta = (real *) malloc( system->N * sizeof( real ) ); + workspace->vlpex = (real *) malloc( system->N * sizeof( real ) ); + + /* QEq storage */ + workspace->H = NULL; + workspace->L = NULL; + workspace->U = NULL; + workspace->droptol = (real *) calloc( system->N, sizeof( real ) ); + workspace->w = (real *) calloc( system->N, sizeof( real ) ); + workspace->Hdia_inv = (real *) calloc( system->N, sizeof( real ) ); + workspace->b = (real *) calloc( system->N * 2, sizeof( real ) ); + workspace->b_s = (real *) calloc( system->N, sizeof( real ) ); + workspace->b_t = (real *) calloc( system->N, sizeof( real ) ); + workspace->b_prc = (real *) calloc( system->N * 2, sizeof( real ) ); + workspace->b_prm = (real *) calloc( system->N * 2, sizeof( real ) ); + workspace->s_t = (real *) calloc( system->N * 2, sizeof( real ) ); + workspace->s = (real**) calloc( 5, sizeof( real* ) ); + workspace->t = (real**) calloc( 5, sizeof( real* ) ); + for ( i = 0; i < 5; ++i ) + { + workspace->s[i] = (real *) calloc( system->N, sizeof( real ) ); + workspace->t[i] = (real *) calloc( system->N, sizeof( real ) ); + } + // workspace->s_old = (real *) calloc( system->N, sizeof( real ) ); + // workspace->t_old = (real *) calloc( system->N, sizeof( real ) ); + // workspace->s_oldest = (real *) calloc( system->N, sizeof( real ) ); + // workspace->t_oldest = (real *) calloc( system->N, sizeof( real ) ); + + for ( i = 0; i < system->N; ++i ) + { + workspace->Hdia_inv[i] = 1. / system->reaxprm.sbp[system->atoms[i].type].eta; + workspace->b_s[i] = -system->reaxprm.sbp[ system->atoms[i].type ].chi; + workspace->b_t[i] = -1.0; + + workspace->b[i] = -system->reaxprm.sbp[ system->atoms[i].type ].chi; + workspace->b[i + system->N] = -1.0; + } + + /* GMRES storage */ + workspace->y = (real *) calloc( RESTART + 1, sizeof( real ) ); + workspace->z = (real *) calloc( RESTART + 1, sizeof( real ) ); + workspace->g = (real *) calloc( RESTART + 1, sizeof( real ) ); + workspace->h = (real **) calloc( RESTART + 1, sizeof( real*) ); + workspace->hs = (real *) calloc( RESTART + 1, sizeof( real ) ); + workspace->hc = (real *) calloc( RESTART + 1, sizeof( real ) ); + workspace->rn = (real **) calloc( RESTART + 1, sizeof( real*) ); + workspace->v = (real **) calloc( RESTART + 1, sizeof( real*) ); + + for ( i = 0; i < RESTART + 1; ++i ) { - workspace->h[i] = (real *) calloc( RESTART+1, sizeof( real ) ); - workspace->rn[i] = (real *) calloc( system->N * 2, sizeof( real ) ); - workspace->v[i] = (real *) calloc( system->N, sizeof( real ) ); + workspace->h[i] = (real *) calloc( RESTART + 1, sizeof( real ) ); + workspace->rn[i] = (real *) calloc( system->N * 2, sizeof( real ) ); + workspace->v[i] = (real *) calloc( system->N, sizeof( real ) ); } - /* CG storage */ - workspace->r = (real *) calloc( system->N, sizeof( real ) ); - workspace->d = (real *) calloc( system->N, sizeof( real ) ); - workspace->q = (real *) calloc( system->N, sizeof( real ) ); - workspace->p = (real *) calloc( system->N, sizeof( real ) ); + /* CG storage */ + workspace->r = (real *) calloc( system->N, sizeof( real ) ); + workspace->d = (real *) calloc( system->N, sizeof( real ) ); + workspace->q = (real *) calloc( system->N, sizeof( real ) ); + workspace->p = (real *) calloc( system->N, sizeof( real ) ); - /* integrator storage */ - workspace->a = (rvec *) malloc( system->N * sizeof( rvec ) ); - workspace->f_old = (rvec *) malloc( system->N * sizeof( rvec ) ); - workspace->v_const = (rvec *) malloc( system->N * sizeof( rvec ) ); + /* integrator storage */ + workspace->a = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->f_old = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->v_const = (rvec *) malloc( system->N * sizeof( rvec ) ); - /* storage for analysis */ - if( control->molec_anal || control->diffusion_coef ) + /* storage for analysis */ + if ( control->molec_anal || control->diffusion_coef ) { - workspace->mark = (int *) calloc( system->N, sizeof(int) ); - workspace->old_mark = (int *) calloc( system->N, sizeof(int) ); + workspace->mark = (int *) calloc( system->N, sizeof(int) ); + workspace->old_mark = (int *) calloc( system->N, sizeof(int) ); } - else - workspace->mark = workspace->old_mark = NULL; - - if( control->diffusion_coef ) - workspace->x_old = (rvec *) calloc( system->N, sizeof( rvec ) ); - else workspace->x_old = NULL; - - + else + workspace->mark = workspace->old_mark = NULL; + + if ( control->diffusion_coef ) + workspace->x_old = (rvec *) calloc( system->N, sizeof( rvec ) ); + else workspace->x_old = NULL; + + #ifdef TEST_FORCES - workspace->dDelta = (rvec *) malloc( system->N * sizeof( rvec ) ); - workspace->f_ele = (rvec *) malloc( system->N * sizeof( rvec ) ); - workspace->f_vdw = (rvec *) malloc( system->N * sizeof( rvec ) ); - workspace->f_bo = (rvec *) malloc( system->N * sizeof( rvec ) ); - workspace->f_be = (rvec *) malloc( system->N * sizeof( rvec ) ); - workspace->f_lp = (rvec *) malloc( system->N * sizeof( rvec ) ); - workspace->f_ov = (rvec *) malloc( system->N * sizeof( rvec ) ); - workspace->f_un = (rvec *) malloc( system->N * sizeof( rvec ) ); - workspace->f_ang = (rvec *) malloc( system->N * sizeof( rvec ) ); - workspace->f_coa = (rvec *) malloc( system->N * sizeof( rvec ) ); - workspace->f_pen = (rvec *) malloc( system->N * sizeof( rvec ) ); - workspace->f_hb = (rvec *) malloc( system->N * sizeof( rvec ) ); - workspace->f_tor = (rvec *) malloc( system->N * sizeof( rvec ) ); - workspace->f_con = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->dDelta = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->f_ele = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->f_vdw = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->f_bo = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->f_be = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->f_lp = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->f_ov = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->f_un = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->f_ang = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->f_coa = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->f_pen = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->f_hb = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->f_tor = (rvec *) malloc( system->N * sizeof( rvec ) ); + workspace->f_con = (rvec *) malloc( system->N * sizeof( rvec ) ); #endif - workspace->realloc.num_far = -1; - workspace->realloc.Htop = -1; - workspace->realloc.hbonds = -1; - workspace->realloc.bonds = -1; - workspace->realloc.num_3body = -1; - workspace->realloc.gcell_atoms = -1; + workspace->realloc.num_far = -1; + workspace->realloc.Htop = -1; + workspace->realloc.hbonds = -1; + workspace->realloc.bonds = -1; + workspace->realloc.num_3body = -1; + workspace->realloc.gcell_atoms = -1; - Reset_Workspace( system, workspace ); + Reset_Workspace( system, workspace ); } -void Init_Lists( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Init_Lists( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i, num_nbrs, num_hbonds, num_bonds, num_3body, Htop; - int *hb_top, *bond_top; - - num_nbrs = Estimate_NumNeighbors( system, control, workspace, lists ); - if( !Make_List(system->N, num_nbrs, TYP_FAR_NEIGHBOR, (*lists)+FAR_NBRS) ) { - fprintf(stderr, "Problem in initializing far nbrs list. Terminating!\n"); - exit( INIT_ERR ); - } + int i, num_nbrs, num_hbonds, num_bonds, num_3body, Htop; + int *hb_top, *bond_top; + + num_nbrs = Estimate_NumNeighbors( system, control, workspace, lists ); + if ( !Make_List(system->N, num_nbrs, TYP_FAR_NEIGHBOR, (*lists) + FAR_NBRS) ) + { + fprintf(stderr, "Problem in initializing far nbrs list. Terminating!\n"); + exit( INIT_ERR ); + } #if defined(DEBUG_FOCUS) - fprintf( stderr, "memory allocated: far_nbrs = %ldMB\n", - num_nbrs * sizeof(far_neighbor_data) / (1024*1024) ); + fprintf( stderr, "memory allocated: far_nbrs = %ldMB\n", + num_nbrs * sizeof(far_neighbor_data) / (1024 * 1024) ); #endif - Generate_Neighbor_Lists(system,control,data,workspace,lists,out_control); - Htop = 0; - hb_top = (int*) calloc( system->N, sizeof(int) ); - bond_top = (int*) calloc( system->N, sizeof(int) ); - num_3body = 0; - Estimate_Storage_Sizes( system, control, lists, - &Htop, hb_top, bond_top, &num_3body ); - - Allocate_Matrix( &(workspace->H), system->N, Htop ); + Generate_Neighbor_Lists(system, control, data, workspace, lists, out_control); + Htop = 0; + hb_top = (int*) calloc( system->N, sizeof(int) ); + bond_top = (int*) calloc( system->N, sizeof(int) ); + num_3body = 0; + Estimate_Storage_Sizes( system, control, lists, + &Htop, hb_top, bond_top, &num_3body ); + + Allocate_Matrix( &(workspace->H), system->N, Htop ); #if defined(DEBUG_FOCUS) - fprintf( stderr, "estimated storage - Htop: %d\n", Htop ); - fprintf( stderr, "memory allocated: H = %ldMB\n", - Htop * sizeof(sparse_matrix_entry) / (1024*1024) ); + fprintf( stderr, "estimated storage - Htop: %d\n", Htop ); + fprintf( stderr, "memory allocated: H = %ldMB\n", + Htop * sizeof(sparse_matrix_entry) / (1024 * 1024) ); #endif - workspace->num_H = 0; - if( control->hb_cut > 0 ) { - /* init H indexes */ - for( i = 0; i < system->N; ++i ) - if( system->reaxprm.sbp[ system->atoms[i].type ].p_hbond == 1 ) // H atom - workspace->hbond_index[i] = workspace->num_H++; - else workspace->hbond_index[i] = -1; - - Allocate_HBond_List( system->N, workspace->num_H, workspace->hbond_index, - hb_top, (*lists)+HBONDS ); - num_hbonds = hb_top[system->N-1]; + workspace->num_H = 0; + if ( control->hb_cut > 0 ) + { + /* init H indexes */ + for ( i = 0; i < system->N; ++i ) + if ( system->reaxprm.sbp[ system->atoms[i].type ].p_hbond == 1 ) // H atom + workspace->hbond_index[i] = workspace->num_H++; + else workspace->hbond_index[i] = -1; + + Allocate_HBond_List( system->N, workspace->num_H, workspace->hbond_index, + hb_top, (*lists) + HBONDS ); + num_hbonds = hb_top[system->N - 1]; #if defined(DEBUG_FOCUS) - fprintf( stderr, "estimated storage - num_hbonds: %d\n", num_hbonds ); - fprintf( stderr, "memory allocated: hbonds = %ldMB\n", - num_hbonds * sizeof(hbond_data) / (1024*1024) ); + 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 - } - - /* bonds list */ - Allocate_Bond_List( system->N, bond_top, (*lists)+BONDS ); - num_bonds = bond_top[system->N-1]; + } + + /* bonds list */ + Allocate_Bond_List( system->N, bond_top, (*lists) + BONDS ); + num_bonds = bond_top[system->N - 1]; #if defined(DEBUG_FOCUS) - fprintf( stderr, "estimated storage - num_bonds: %d\n", num_bonds ); - fprintf( stderr, "memory allocated: bonds = %ldMB\n", - num_bonds * sizeof(bond_data) / (1024*1024) ); + fprintf( stderr, "estimated storage - num_bonds: %d\n", num_bonds ); + fprintf( stderr, "memory allocated: bonds = %ldMB\n", + num_bonds * sizeof(bond_data) / (1024 * 1024) ); #endif //fprintf (stderr, " **** sizeof 3 body : %d \n", sizeof (three_body_interaction_data)); //fprintf (stderr, " **** num_3body : %d \n", num_3body); //fprintf (stderr, " **** num_bonds : %d \n", num_bonds); - /* 3bodies list */ - if(!Make_List(num_bonds, num_3body, TYP_THREE_BODY, (*lists)+THREE_BODIES)) { - fprintf( stderr, "Problem in initializing angles list. Terminating!\n" ); - exit( INIT_ERR ); - } + /* 3bodies list */ + if (!Make_List(num_bonds, num_3body, TYP_THREE_BODY, (*lists) + THREE_BODIES)) + { + fprintf( stderr, "Problem in initializing angles list. Terminating!\n" ); + exit( INIT_ERR ); + } #if defined(DEBUG_FOCUS) - fprintf( stderr, "estimated storage - num_3body: %d\n", num_3body ); - fprintf( stderr, "memory allocated: 3-body = %ldMB\n", - num_3body * sizeof(three_body_interaction_data) / (1024*1024) ); + fprintf( stderr, "estimated storage - num_3body: %d\n", num_3body ); + fprintf( stderr, "memory allocated: 3-body = %ldMB\n", + num_3body * sizeof(three_body_interaction_data) / (1024 * 1024) ); #endif #ifdef TEST_FORCES - if(!Make_List( system->N, num_bonds * 8, TYP_DDELTA, (*lists) + DDELTA )) { - fprintf( stderr, "Problem in initializing dDelta list. Terminating!\n" ); - exit( INIT_ERR ); - } - - if( !Make_List( num_bonds, num_bonds*MAX_BONDS*3, TYP_DBO, (*lists)+DBO ) ) { - fprintf( stderr, "Problem in initializing dBO list. Terminating!\n" ); - exit( INIT_ERR ); - } + if (!Make_List( system->N, num_bonds * 8, TYP_DDELTA, (*lists) + DDELTA )) + { + fprintf( stderr, "Problem in initializing dDelta list. Terminating!\n" ); + exit( INIT_ERR ); + } + + if ( !Make_List( num_bonds, num_bonds * MAX_BONDS * 3, TYP_DBO, (*lists) + DBO ) ) + { + fprintf( stderr, "Problem in initializing dBO list. Terminating!\n" ); + exit( INIT_ERR ); + } #endif - free( hb_top ); - free( bond_top ); + free( hb_top ); + free( bond_top ); } -void Init_Out_Controls(reax_system *system, control_params *control, - static_storage *workspace, output_controls *out_control) +void Init_Out_Controls(reax_system *system, control_params *control, + static_storage *workspace, output_controls *out_control) { - char temp[1000]; + char temp[1000]; - /* Init trajectory file */ - if( out_control->write_steps > 0 ) { + /* Init trajectory file */ + if ( out_control->write_steps > 0 ) + { + strcpy( temp, control->sim_name ); + strcat( temp, ".trj" ); + out_control->trj = fopen( temp, "w" ); + out_control->write_header( system, control, workspace, out_control ); + } + + if ( out_control->energy_update_freq > 0 ) + { + /* Init out file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".out" ); + out_control->out = fopen( temp, "w" ); + fprintf( out_control->out, "%-6s%16s%16s%16s%11s%11s%13s%13s%13s\n", + "step", "total energy", "poten. energy", "kin. energy", + "temp.", "target", "volume", "press.", "target" ); + fflush( out_control->out ); + + /* Init potentials file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".pot" ); + out_control->pot = fopen( temp, "w" ); + fprintf( out_control->pot, + "%-6s%13s%13s%13s%13s%13s%13s%13s%13s%13s%13s%13s\n", + "step", "ebond", "eatom", "elp", "eang", "ecoa", "ehb", + "etor", "econj", "evdw", "ecoul", "epol" ); + fflush( out_control->pot ); + + /* Init log file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".log" ); + out_control->log = fopen( temp, "w" ); + fprintf( out_control->log, "%-6s%10s%10s%10s%10s%10s%10s%10s\n", + "step", "total", "neighbors", "init", "bonded", + "nonbonded", "QEq", "matvec" ); + } + + /* Init pressure file */ + if ( control->ensemble == NPT || + control->ensemble == iNPT || + control->ensemble == sNPT ) + { + strcpy( temp, control->sim_name ); + strcat( temp, ".prs" ); + out_control->prs = fopen( temp, "w" ); + fprintf( out_control->prs, "%-6s%13s%13s%13s%13s%13s%13s%13s%13s\n", + "step", "norm_x", "norm_y", "norm_z", + "press_x", "press_y", "press_z", "target_p", "volume" ); + fflush( out_control->prs ); + } + + /* Init molecular analysis file */ + if ( control->molec_anal ) + { + sprintf( temp, "%s.mol", control->sim_name ); + out_control->mol = fopen( temp, "w" ); + if ( control->num_ignored ) + { + sprintf( temp, "%s.ign", control->sim_name ); + out_control->ign = fopen( temp, "w" ); + } + } + + /* Init electric dipole moment analysis file */ + if ( control->dipole_anal ) + { + strcpy( temp, control->sim_name ); + strcat( temp, ".dpl" ); + out_control->dpl = fopen( temp, "w" ); + fprintf( out_control->dpl, + "Step Molecule Count Avg. Dipole Moment Norm\n" ); + fflush( out_control->dpl ); + } + + /* Init diffusion coef analysis file */ + if ( control->diffusion_coef ) + { + strcpy( temp, control->sim_name ); + strcat( temp, ".drft" ); + out_control->drft = fopen( temp, "w" ); + fprintf( out_control->drft, "Step Type Count Avg Squared Disp\n" ); + fflush( out_control->drft ); + } + + +#ifdef TEST_ENERGY + /* open bond energy file */ strcpy( temp, control->sim_name ); - strcat( temp, ".trj" ); - out_control->trj = fopen( temp, "w" ); - out_control->write_header( system, control, workspace, out_control ); - } + strcat( temp, ".ebond" ); + out_control->ebond = fopen( temp, "w" ); - if( out_control->energy_update_freq > 0 ) { - /* Init out file */ + /* open lone-pair energy file */ strcpy( temp, control->sim_name ); - strcat( temp, ".out" ); - out_control->out = fopen( temp, "w" ); - fprintf( out_control->out, "%-6s%16s%16s%16s%11s%11s%13s%13s%13s\n", - "step", "total energy", "poten. energy", "kin. energy", - "temp.", "target", "volume", "press.", "target" ); - fflush( out_control->out ); - - /* Init potentials file */ + strcat( temp, ".elp" ); + out_control->elp = fopen( temp, "w" ); + + /* open overcoordination energy file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".eov" ); + out_control->eov = fopen( temp, "w" ); + + /* open undercoordination energy file */ strcpy( temp, control->sim_name ); - strcat( temp, ".pot" ); - out_control->pot = fopen( temp, "w" ); - fprintf( out_control->pot, - "%-6s%13s%13s%13s%13s%13s%13s%13s%13s%13s%13s%13s\n", - "step", "ebond", "eatom", "elp", "eang", "ecoa", "ehb", - "etor", "econj", "evdw","ecoul", "epol" ); - fflush( out_control->pot ); - - /* Init log file */ + strcat( temp, ".eun" ); + out_control->eun = fopen( temp, "w" ); + + /* open angle energy file */ strcpy( temp, control->sim_name ); - strcat( temp, ".log" ); - out_control->log = fopen( temp, "w" ); - fprintf( out_control->log, "%-6s%10s%10s%10s%10s%10s%10s%10s\n", - "step", "total", "neighbors", "init", "bonded", - "nonbonded", "QEq", "matvec" ); - } - - /* Init pressure file */ - if( control->ensemble == NPT || - control->ensemble == iNPT || - control->ensemble == sNPT ) { + strcat( temp, ".eval" ); + out_control->eval = fopen( temp, "w" ); + + /* open penalty energy file */ strcpy( temp, control->sim_name ); - strcat( temp, ".prs" ); - out_control->prs = fopen( temp, "w" ); - fprintf( out_control->prs, "%-6s%13s%13s%13s%13s%13s%13s%13s%13s\n", - "step", "norm_x", "norm_y", "norm_z", - "press_x", "press_y", "press_z", "target_p", "volume" ); - fflush( out_control->prs ); - } - - /* Init molecular analysis file */ - if( control->molec_anal ) { - sprintf( temp, "%s.mol", control->sim_name ); - out_control->mol = fopen( temp, "w" ); - if( control->num_ignored ) { - sprintf( temp, "%s.ign", control->sim_name ); - out_control->ign = fopen( temp, "w" ); - } - } - - /* Init electric dipole moment analysis file */ - if( control->dipole_anal ) { + strcat( temp, ".epen" ); + out_control->epen = fopen( temp, "w" ); + + /* open coalition energy file */ strcpy( temp, control->sim_name ); - strcat( temp, ".dpl" ); - out_control->dpl = fopen( temp, "w" ); - fprintf( out_control->dpl, - "Step Molecule Count Avg. Dipole Moment Norm\n" ); - fflush( out_control->dpl ); - } - - /* Init diffusion coef analysis file */ - if( control->diffusion_coef ) { + strcat( temp, ".ecoa" ); + out_control->ecoa = fopen( temp, "w" ); + + /* open hydrogen bond energy file */ strcpy( temp, control->sim_name ); - strcat( temp, ".drft" ); - out_control->drft = fopen( temp, "w" ); - fprintf( out_control->drft, "Step Type Count Avg Squared Disp\n" ); - fflush( out_control->drft ); - } + strcat( temp, ".ehb" ); + out_control->ehb = fopen( temp, "w" ); + /* open torsion energy file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".etor" ); + out_control->etor = fopen( temp, "w" ); -#ifdef TEST_ENERGY - /* open bond energy file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".ebond" ); - out_control->ebond = fopen( temp, "w" ); - - /* open lone-pair energy file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".elp" ); - out_control->elp = fopen( temp, "w" ); - - /* open overcoordination energy file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".eov" ); - out_control->eov = fopen( temp, "w" ); - - /* open undercoordination energy file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".eun" ); - out_control->eun = fopen( temp, "w" ); - - /* open angle energy file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".eval" ); - out_control->eval = fopen( temp, "w" ); - - /* open penalty energy file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".epen" ); - out_control->epen = fopen( temp, "w" ); - - /* open coalition energy file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".ecoa" ); - out_control->ecoa = fopen( temp, "w" ); - - /* open hydrogen bond energy file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".ehb" ); - out_control->ehb = fopen( temp, "w" ); - - /* open torsion energy file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".etor" ); - out_control->etor = fopen( temp, "w" ); - - /* open conjugation energy file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".econ" ); - out_control->econ = fopen( temp, "w" ); - - /* open vdWaals energy file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".evdw" ); - out_control->evdw = fopen( temp, "w" ); - - /* open coulomb energy file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".ecou" ); - out_control->ecou = fopen( temp, "w" ); + /* open conjugation energy file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".econ" ); + out_control->econ = fopen( temp, "w" ); + + /* open vdWaals energy file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".evdw" ); + out_control->evdw = fopen( temp, "w" ); + + /* open coulomb energy file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".ecou" ); + out_control->ecou = fopen( temp, "w" ); #endif #ifdef TEST_FORCES - /* open bond orders file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".fbo" ); - out_control->fbo = fopen( temp, "w" ); - - /* open bond orders derivatives file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".fdbo" ); - out_control->fdbo = fopen( temp, "w" ); - - /* open bond forces file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".fbond" ); - out_control->fbond = fopen( temp, "w" ); - - /* open lone-pair forces file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".flp" ); - out_control->flp = fopen( temp, "w" ); - - /* open overcoordination forces file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".fatom" ); - out_control->fatom = fopen( temp, "w" ); - - /* open angle forces file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".f3body" ); - out_control->f3body = fopen( temp, "w" ); - - /* open hydrogen bond forces file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".fhb" ); - out_control->fhb = fopen( temp, "w" ); - - /* open torsion forces file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".f4body" ); - out_control->f4body = fopen( temp, "w" ); - - /* open nonbonded forces file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".fnonb" ); - out_control->fnonb = fopen( temp, "w" ); - - /* open total force file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".ftot" ); - out_control->ftot = fopen( temp, "w" ); - - /* open coulomb forces file */ - strcpy( temp, control->sim_name ); - strcat( temp, ".ftot2" ); - out_control->ftot2 = fopen( temp, "w" ); + /* open bond orders file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".fbo" ); + out_control->fbo = fopen( temp, "w" ); + + /* open bond orders derivatives file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".fdbo" ); + out_control->fdbo = fopen( temp, "w" ); + + /* open bond forces file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".fbond" ); + out_control->fbond = fopen( temp, "w" ); + + /* open lone-pair forces file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".flp" ); + out_control->flp = fopen( temp, "w" ); + + /* open overcoordination forces file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".fatom" ); + out_control->fatom = fopen( temp, "w" ); + + /* open angle forces file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".f3body" ); + out_control->f3body = fopen( temp, "w" ); + + /* open hydrogen bond forces file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".fhb" ); + out_control->fhb = fopen( temp, "w" ); + + /* open torsion forces file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".f4body" ); + out_control->f4body = fopen( temp, "w" ); + + /* open nonbonded forces file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".fnonb" ); + out_control->fnonb = fopen( temp, "w" ); + + /* open total force file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".ftot" ); + out_control->ftot = fopen( temp, "w" ); + + /* open coulomb forces file */ + strcpy( temp, control->sim_name ); + strcat( temp, ".ftot2" ); + out_control->ftot2 = fopen( temp, "w" ); #endif -/* Error handling */ - /* if ( out_control->out == NULL || out_control->pot == NULL || - out_control->log == NULL || out_control->mol == NULL || - out_control->dpl == NULL || out_control->drft == NULL || - out_control->pdb == NULL ) - { - fprintf( stderr, "FILE OPEN ERROR. TERMINATING..." ); - exit( CANNOT_OPEN_OUTFILE ); - }*/ + /* Error handling */ + /* if ( out_control->out == NULL || out_control->pot == NULL || + out_control->log == NULL || out_control->mol == NULL || + out_control->dpl == NULL || out_control->drft == NULL || + out_control->pdb == NULL ) + { + fprintf( stderr, "FILE OPEN ERROR. TERMINATING..." ); + exit( CANNOT_OPEN_OUTFILE ); + }*/ } -void Initialize(reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, list **lists, - output_controls *out_control, evolve_function *Evolve) +void Initialize(reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, list **lists, + output_controls *out_control, evolve_function *Evolve) { - real start, end; - Randomize(); + real start, end; + Randomize(); - Init_System( system, control, data ); + Init_System( system, control, data ); - Init_Simulation_Data( system, control, data, out_control, Evolve ); + Init_Simulation_Data( system, control, data, out_control, Evolve ); - Init_Workspace( system, control, workspace ); - - Init_Lists( system, control, data, workspace, lists, out_control ); + Init_Workspace( system, control, workspace ); - Init_Out_Controls( system, control, workspace, out_control ); + Init_Lists( system, control, data, workspace, lists, out_control ); - /* These are done in forces.c, only forces.c can see all those functions */ - Init_Bonded_Force_Functions( control ); + Init_Out_Controls( system, control, workspace, out_control ); + + /* These are done in forces.c, only forces.c can see all those functions */ + Init_Bonded_Force_Functions( control ); #ifdef TEST_FORCES - Init_Force_Test_Functions( ); + Init_Force_Test_Functions( ); #endif - if( control->tabulate ) { - start = Get_Time (); - Make_LR_Lookup_Table( system, control ); - end = Get_Timing_Info (start); + if ( control->tabulate ) + { + start = Get_Time (); + Make_LR_Lookup_Table( system, control ); + end = Get_Timing_Info (start); - //fprintf (stderr, "Time for LR Lookup Table calculation is %f \n", end ); - } + //fprintf (stderr, "Time for LR Lookup Table calculation is %f \n", end ); + } #if defined(DEBUG_FOCUS) - fprintf( stderr, "data structures have been initialized...\n" ); + fprintf( stderr, "data structures have been initialized...\n" ); #endif } diff --git a/puremd_rc_1003/sPuReMD/init_md.h b/puremd_rc_1003/sPuReMD/init_md.h index 52b78a82..3fc59053 100644 --- a/puremd_rc_1003/sPuReMD/init_md.h +++ b/puremd_rc_1003/sPuReMD/init_md.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -25,6 +25,6 @@ #include "mytypes.h" void Initialize( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls*, evolve_function* ); + static_storage*, list**, output_controls*, evolve_function* ); #endif diff --git a/puremd_rc_1003/sPuReMD/integrate.c b/puremd_rc_1003/sPuReMD/integrate.c index 6316ad86..142863ca 100644 --- a/puremd_rc_1003/sPuReMD/integrate.c +++ b/puremd_rc_1003/sPuReMD/integrate.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -35,382 +35,397 @@ -void Velocity_Verlet_NVE(reax_system* system, control_params* control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Velocity_Verlet_NVE(reax_system* system, control_params* control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i, steps, renbr; - real inv_m, dt, dt_sqr; - rvec dx; - - dt = control->dt; - dt_sqr = SQR(dt); - steps = data->step - data->prev_steps; - renbr = (steps % control->reneighbor == 0); -#if defined(DEBUG_FOCUS) - fprintf( stderr, "step%d: ", data->step ); + int i, steps, renbr; + real inv_m, dt, dt_sqr; + rvec dx; + + dt = control->dt; + dt_sqr = SQR(dt); + steps = data->step - data->prev_steps; + renbr = (steps % control->reneighbor == 0); +#if defined(DEBUG_FOCUS) + fprintf( stderr, "step%d: ", data->step ); #endif - for( i = 0; i < system->N; i++ ) { - inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; - - rvec_ScaledSum( dx, dt, system->atoms[i].v, - 0.5 * dt_sqr * -F_CONV * inv_m, system->atoms[i].f ); - Inc_on_T3( system->atoms[i].x, dx, &( system->box ) ); - - rvec_ScaledAdd( system->atoms[i].v, - 0.5 * dt * -F_CONV * inv_m, system->atoms[i].f ); - } -#if defined(DEBUG_FOCUS) - fprintf( stderr, "verlet1 - "); + for ( i = 0; i < system->N; i++ ) + { + inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; + + rvec_ScaledSum( dx, dt, system->atoms[i].v, + 0.5 * dt_sqr * -F_CONV * inv_m, system->atoms[i].f ); + Inc_on_T3( system->atoms[i].x, dx, &( system->box ) ); + + rvec_ScaledAdd( system->atoms[i].v, + 0.5 * dt * -F_CONV * inv_m, system->atoms[i].f ); + } +#if defined(DEBUG_FOCUS) + fprintf( stderr, "verlet1 - "); #endif - Reallocate( system, workspace, lists, renbr ); - Reset( system, control, data, workspace, lists ); - if( renbr ) - Generate_Neighbor_Lists( system, control, data, workspace, - lists, out_control ); - Compute_Forces( system, control, data, workspace, lists, out_control ); - - for( i = 0; i < system->N; i++ ) { - inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; - rvec_ScaledAdd( system->atoms[i].v, - 0.5 * dt * -F_CONV * inv_m, system->atoms[i].f ); - } -#if defined(DEBUG_FOCUS) - fprintf( stderr, "verlet2\n"); + Reallocate( system, workspace, lists, renbr ); + Reset( system, control, data, workspace, lists ); + if ( renbr ) + Generate_Neighbor_Lists( system, control, data, workspace, + lists, out_control ); + Compute_Forces( system, control, data, workspace, lists, out_control ); + + for ( i = 0; i < system->N; i++ ) + { + inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; + rvec_ScaledAdd( system->atoms[i].v, + 0.5 * dt * -F_CONV * inv_m, system->atoms[i].f ); + } +#if defined(DEBUG_FOCUS) + fprintf( stderr, "verlet2\n"); #endif } -void Velocity_Verlet_Nose_Hoover_NVT_Klein(reax_system* system, - control_params* control, - simulation_data *data, - static_storage *workspace, - list **lists, - output_controls *out_control ) +void Velocity_Verlet_Nose_Hoover_NVT_Klein(reax_system* system, + control_params* control, + simulation_data *data, + static_storage *workspace, + list **lists, + output_controls *out_control ) { - int i, itr, steps, renbr; - real inv_m, coef_v, dt, dt_sqr; - real E_kin_new, G_xi_new, v_xi_new, v_xi_old; - rvec dx; - thermostat *therm; - - dt = control->dt; - dt_sqr = SQR( dt ); - therm = &( data->therm ); - steps = data->step - data->prev_steps; - renbr = (steps % control->reneighbor == 0); + int i, itr, steps, renbr; + real inv_m, coef_v, dt, dt_sqr; + real E_kin_new, G_xi_new, v_xi_new, v_xi_old; + rvec dx; + thermostat *therm; + + dt = control->dt; + dt_sqr = SQR( dt ); + therm = &( data->therm ); + steps = data->step - data->prev_steps; + renbr = (steps % control->reneighbor == 0); #if defined(DEBUG_FOCUS) - fprintf( stderr, "step%d: ", data->step ); + fprintf( stderr, "step%d: ", data->step ); #endif - - /* Compute x(t + dt) and copy old forces */ - for (i=0; i < system->N; i++) { - inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; - - rvec_ScaledSum( dx, dt - 0.5 * dt_sqr * therm->v_xi, system->atoms[i].v, - 0.5 * dt_sqr * inv_m * -F_CONV, system->atoms[i].f ); - - Inc_on_T3( system->atoms[i].x, dx, &(system->box) ); - - rvec_Copy( workspace->f_old[i], system->atoms[i].f ); - } - /* Compute xi(t + dt) */ - therm->xi += ( therm->v_xi * dt + 0.5 * dt_sqr * therm->G_xi ); + + /* Compute x(t + dt) and copy old forces */ + for (i = 0; i < system->N; i++) + { + inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; + + rvec_ScaledSum( dx, dt - 0.5 * dt_sqr * therm->v_xi, system->atoms[i].v, + 0.5 * dt_sqr * inv_m * -F_CONV, system->atoms[i].f ); + + Inc_on_T3( system->atoms[i].x, dx, &(system->box) ); + + rvec_Copy( workspace->f_old[i], system->atoms[i].f ); + } + /* Compute xi(t + dt) */ + therm->xi += ( therm->v_xi * dt + 0.5 * dt_sqr * therm->G_xi ); #if defined(DEBUG_FOCUS) - fprintf( stderr, "verlet1 - " ); + fprintf( stderr, "verlet1 - " ); #endif - - Reallocate( system, workspace, lists, renbr ); - Reset( system, control, data, workspace, lists ); - if( renbr ) - Generate_Neighbor_Lists( system, control, data, workspace, - lists, out_control ); - /* Calculate Forces at time (t + dt) */ - Compute_Forces( system,control,data, workspace, lists, out_control ); - - /* Compute iteration constants for each atom's velocity */ - for( i = 0; i < system->N; ++i ) { - inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; - - rvec_Scale( workspace->v_const[i], - 1.0 - 0.5 * dt * therm->v_xi, system->atoms[i].v ); - rvec_ScaledAdd( workspace->v_const[i], - 0.5 * dt * inv_m * -F_CONV, workspace->f_old[i] ); - rvec_ScaledAdd( workspace->v_const[i], - 0.5 * dt * inv_m * -F_CONV, system->atoms[i].f ); + + Reallocate( system, workspace, lists, renbr ); + Reset( system, control, data, workspace, lists ); + if ( renbr ) + Generate_Neighbor_Lists( system, control, data, workspace, + lists, out_control ); + /* Calculate Forces at time (t + dt) */ + Compute_Forces( system, control, data, workspace, lists, out_control ); + + /* Compute iteration constants for each atom's velocity */ + for ( i = 0; i < system->N; ++i ) + { + inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; + + rvec_Scale( workspace->v_const[i], + 1.0 - 0.5 * dt * therm->v_xi, system->atoms[i].v ); + rvec_ScaledAdd( workspace->v_const[i], + 0.5 * dt * inv_m * -F_CONV, workspace->f_old[i] ); + rvec_ScaledAdd( workspace->v_const[i], + 0.5 * dt * inv_m * -F_CONV, system->atoms[i].f ); #if defined(DEBUG) - fprintf( stderr, "atom%d: inv_m=%f, C1=%f, C2=%f, v_const=%f %f %f\n", - i, inv_m, 1.0 - 0.5 * dt * therm->v_xi, - 0.5 * dt * inv_m * -F_CONV, workspace->v_const[i][0], - workspace->v_const[i][1], workspace->v_const[i][2] ); + fprintf( stderr, "atom%d: inv_m=%f, C1=%f, C2=%f, v_const=%f %f %f\n", + i, inv_m, 1.0 - 0.5 * dt * therm->v_xi, + 0.5 * dt * inv_m * -F_CONV, workspace->v_const[i][0], + workspace->v_const[i][1], workspace->v_const[i][2] ); #endif - } - - v_xi_new = therm->v_xi_old + 2.0 * dt * therm->G_xi; - E_kin_new = G_xi_new = v_xi_old = 0; - itr = 0; - do { - itr++; - - /* new values become old in this iteration */ - v_xi_old = v_xi_new; - coef_v = 1.0 / (1.0 + 0.5 * dt * v_xi_old); - E_kin_new = 0; - for( i = 0; i < system->N; ++i ) { - rvec_Scale( system->atoms[i].v, coef_v, workspace->v_const[i] ); - - E_kin_new += ( 0.5*system->reaxprm.sbp[system->atoms[i].type].mass * - rvec_Dot( system->atoms[i].v, system->atoms[i].v ) ); + } + + v_xi_new = therm->v_xi_old + 2.0 * dt * therm->G_xi; + E_kin_new = G_xi_new = v_xi_old = 0; + itr = 0; + do + { + itr++; + + /* new values become old in this iteration */ + v_xi_old = v_xi_new; + coef_v = 1.0 / (1.0 + 0.5 * dt * v_xi_old); + E_kin_new = 0; + for ( i = 0; i < system->N; ++i ) + { + rvec_Scale( system->atoms[i].v, coef_v, workspace->v_const[i] ); + + E_kin_new += ( 0.5 * system->reaxprm.sbp[system->atoms[i].type].mass * + rvec_Dot( system->atoms[i].v, system->atoms[i].v ) ); #if defined(DEBUG) - fprintf( stderr, "itr%d-atom%d: coef_v = %f, v_xi_old = %f\n", - itr, i, coef_v, v_xi_old ); + fprintf( stderr, "itr%d-atom%d: coef_v = %f, v_xi_old = %f\n", + itr, i, coef_v, v_xi_old ); #endif - } - - G_xi_new = control->Tau_T * ( 2.0 * E_kin_new - - data->N_f * K_B * control->T ); - v_xi_new = therm->v_xi + 0.5 * dt * ( therm->G_xi + G_xi_new ); + } + + G_xi_new = control->Tau_T * ( 2.0 * E_kin_new - + data->N_f * K_B * control->T ); + v_xi_new = therm->v_xi + 0.5 * dt * ( therm->G_xi + G_xi_new ); #if defined(DEBUG) - fprintf( stderr, "itr%d: G_xi_new = %f, v_xi_new = %f, v_xi_old = %f\n", - itr, G_xi_new, v_xi_new, v_xi_old ); + fprintf( stderr, "itr%d: G_xi_new = %f, v_xi_new = %f, v_xi_old = %f\n", + itr, G_xi_new, v_xi_new, v_xi_old ); +#endif + } + while ( fabs(v_xi_new - v_xi_old ) > 1e-5 ); + + therm->v_xi_old = therm->v_xi; + therm->v_xi = v_xi_new; + therm->G_xi = G_xi_new; +#if defined(DEBUG_FOCUS) + fprintf( stderr, "vel scale\n" ); #endif - } - while( fabs(v_xi_new - v_xi_old ) > 1e-5 ); - - therm->v_xi_old = therm->v_xi; - therm->v_xi = v_xi_new; - therm->G_xi = G_xi_new; -#if defined(DEBUG_FOCUS) - fprintf( stderr,"vel scale\n" ); -#endif } -/* uses Berendsen-type coupling for both T and P. - All box dimensions are scaled by the same amount, +/* uses Berendsen-type coupling for both T and P. + All box dimensions are scaled by the same amount, there is no change in the angles between axes. */ -void Velocity_Verlet_Berendsen_Isotropic_NPT( reax_system* system, - control_params* control, - simulation_data *data, - static_storage *workspace, - list **lists, - output_controls *out_control ) +void Velocity_Verlet_Berendsen_Isotropic_NPT( reax_system* system, + control_params* control, + simulation_data *data, + static_storage *workspace, + list **lists, + output_controls *out_control ) { - int i, steps, renbr; - real inv_m, dt, lambda, mu; - rvec dx; + int i, steps, renbr; + real inv_m, dt, lambda, mu; + rvec dx; - dt = control->dt; - steps = data->step - data->prev_steps; - renbr = (steps % control->reneighbor == 0); + dt = control->dt; + steps = data->step - data->prev_steps; + renbr = (steps % control->reneighbor == 0); #if defined(DEBUG_FOCUS) - //fprintf( out_control->prs, - // "tau_t: %g tau_p: %g dt/tau_t: %g dt/tau_p: %g\n", - //control->Tau_T, control->Tau_P, dt / control->Tau_T, dt / control->Tau_P ); - fprintf( stderr, "step %d: ", data->step ); + //fprintf( out_control->prs, + // "tau_t: %g tau_p: %g dt/tau_t: %g dt/tau_p: %g\n", + //control->Tau_T, control->Tau_P, dt / control->Tau_T, dt / control->Tau_P ); + fprintf( stderr, "step %d: ", data->step ); #endif - /* velocity verlet, 1st part */ - for( i = 0; i < system->N; i++ ) { - inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; - /* Compute x(t + dt) */ - rvec_ScaledSum( dx, dt, system->atoms[i].v, - 0.5 * -F_CONV * inv_m * SQR(dt), system->atoms[i].f ); - Inc_on_T3( system->atoms[i].x, dx, &(system->box) ); - /* Compute v(t + dt/2) */ - rvec_ScaledAdd( system->atoms[i].v, - 0.5 * -F_CONV * inv_m * dt, system->atoms[i].f ); - /*fprintf( stderr, "%6d %15.8f %15.8f %15.8f %15.8f %15.8f %15.8f\n", - workspace->orig_id[i], - system->atoms[i].x[0], system->atoms[i].x[1], system->atoms[i].x[2], - 0.5 * SQR(dt) * -F_CONV * inv_m * system->atoms[i].f[0], - 0.5 * SQR(dt) * -F_CONV * inv_m * system->atoms[i].f[1], - 0.5 * SQR(dt) * -F_CONV * inv_m * system->atoms[i].f[2] ); */ - } -#if defined(DEBUG_FOCUS) - fprintf( stderr, "verlet1 - " ); + /* velocity verlet, 1st part */ + for ( i = 0; i < system->N; i++ ) + { + inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; + /* Compute x(t + dt) */ + rvec_ScaledSum( dx, dt, system->atoms[i].v, + 0.5 * -F_CONV * inv_m * SQR(dt), system->atoms[i].f ); + Inc_on_T3( system->atoms[i].x, dx, &(system->box) ); + /* Compute v(t + dt/2) */ + rvec_ScaledAdd( system->atoms[i].v, + 0.5 * -F_CONV * inv_m * dt, system->atoms[i].f ); + /*fprintf( stderr, "%6d %15.8f %15.8f %15.8f %15.8f %15.8f %15.8f\n", + workspace->orig_id[i], + system->atoms[i].x[0], system->atoms[i].x[1], system->atoms[i].x[2], + 0.5 * SQR(dt) * -F_CONV * inv_m * system->atoms[i].f[0], + 0.5 * SQR(dt) * -F_CONV * inv_m * system->atoms[i].f[1], + 0.5 * SQR(dt) * -F_CONV * inv_m * system->atoms[i].f[2] ); */ + } +#if defined(DEBUG_FOCUS) + fprintf( stderr, "verlet1 - " ); #endif - Reallocate( system, workspace, lists, renbr ); - Reset( system, control, data, workspace, lists ); - if( renbr ) { - Update_Grid( system ); - Generate_Neighbor_Lists( system, control, data, workspace, - lists, out_control ); - } - Compute_Forces( system, control, data, workspace, lists, out_control ); - - /* velocity verlet, 2nd part */ - for( i = 0; i < system->N; i++ ) { - inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; - /* Compute v(t + dt) */ - rvec_ScaledAdd( system->atoms[i].v, - 0.5 * dt * -F_CONV * inv_m, system->atoms[i].f ); - /* fprintf( stderr, "%6d %15f %15f %15f %15.8f %15.8f %15.8f\n", - workspace->orig_id[i], - system->atoms[i].v[0], system->atoms[i].v[1], system->atoms[i].v[2], - 0.5 * dt * -F_CONV * inv_m * system->atoms[i].f[0], - 0.5 * dt * -F_CONV * inv_m * system->atoms[i].f[1], - 0.5 * dt * -F_CONV * inv_m * system->atoms[i].f[2] );*/ - } - Compute_Kinetic_Energy( system, data ); - Compute_Pressure_Isotropic( system, control, data, out_control ); -#if defined(DEBUG_FOCUS) - fprintf( stderr, "verlet2 - " ); + Reallocate( system, workspace, lists, renbr ); + Reset( system, control, data, workspace, lists ); + if ( renbr ) + { + Update_Grid( system ); + Generate_Neighbor_Lists( system, control, data, workspace, + lists, out_control ); + } + Compute_Forces( system, control, data, workspace, lists, out_control ); + + /* velocity verlet, 2nd part */ + for ( i = 0; i < system->N; i++ ) + { + inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; + /* Compute v(t + dt) */ + rvec_ScaledAdd( system->atoms[i].v, + 0.5 * dt * -F_CONV * inv_m, system->atoms[i].f ); + /* fprintf( stderr, "%6d %15f %15f %15f %15.8f %15.8f %15.8f\n", + workspace->orig_id[i], + system->atoms[i].v[0], system->atoms[i].v[1], system->atoms[i].v[2], + 0.5 * dt * -F_CONV * inv_m * system->atoms[i].f[0], + 0.5 * dt * -F_CONV * inv_m * system->atoms[i].f[1], + 0.5 * dt * -F_CONV * inv_m * system->atoms[i].f[2] );*/ + } + Compute_Kinetic_Energy( system, data ); + Compute_Pressure_Isotropic( system, control, data, out_control ); +#if defined(DEBUG_FOCUS) + fprintf( stderr, "verlet2 - " ); #endif - /* pressure scaler */ - mu = POW( 1.0 + (dt / control->Tau_P[0]) * (data->iso_bar.P - control->P[0]), - 1.0 / 3 ); - if( mu < MIN_dV ) - mu = MIN_dV; - else if( mu > MAX_dV ) - mu = MAX_dV; - - /* temperature scaler */ - lambda = 1.0 + (dt / control->Tau_T) * (control->T / data->therm.T - 1.0); - if( lambda < MIN_dT ) - lambda = MIN_dT; - else if (lambda > MAX_dT ) - lambda = MAX_dT; - lambda = SQRT( lambda ); - - /* Scale velocities and positions at t+dt */ - for( i = 0; i < system->N; ++i ) { - rvec_Scale( system->atoms[i].v, lambda, system->atoms[i].v ); - /* IMPORTANT: What Adri does with scaling positions first to - unit coordinates and then back to cartesian coordinates essentially - is scaling the coordinates with mu^2. However, this causes unphysical - modifications on the system because box dimensions - are being scaled with mu! We need to discuss this with Adri! */ - rvec_Scale( system->atoms[i].x, mu, system->atoms[i].x ); - } - Compute_Kinetic_Energy( system, data ); -#if defined(DEBUG_FOCUS) - fprintf( stderr, "scaling - " ); + /* pressure scaler */ + mu = POW( 1.0 + (dt / control->Tau_P[0]) * (data->iso_bar.P - control->P[0]), + 1.0 / 3 ); + if ( mu < MIN_dV ) + mu = MIN_dV; + else if ( mu > MAX_dV ) + mu = MAX_dV; + + /* temperature scaler */ + lambda = 1.0 + (dt / control->Tau_T) * (control->T / data->therm.T - 1.0); + if ( lambda < MIN_dT ) + lambda = MIN_dT; + else if (lambda > MAX_dT ) + lambda = MAX_dT; + lambda = SQRT( lambda ); + + /* Scale velocities and positions at t+dt */ + for ( i = 0; i < system->N; ++i ) + { + rvec_Scale( system->atoms[i].v, lambda, system->atoms[i].v ); + /* IMPORTANT: What Adri does with scaling positions first to + unit coordinates and then back to cartesian coordinates essentially + is scaling the coordinates with mu^2. However, this causes unphysical + modifications on the system because box dimensions + are being scaled with mu! We need to discuss this with Adri! */ + rvec_Scale( system->atoms[i].x, mu, system->atoms[i].x ); + } + Compute_Kinetic_Energy( system, data ); +#if defined(DEBUG_FOCUS) + fprintf( stderr, "scaling - " ); #endif - Update_Box_Isotropic( &(system->box), mu ); + Update_Box_Isotropic( &(system->box), mu ); #if defined(DEBUG_FOCUS) - fprintf( stderr, "updated box\n" ); + fprintf( stderr, "updated box\n" ); #endif } -/* uses Berendsen-type coupling for both T and P. - All box dimensions are scaled by the same amount, +/* uses Berendsen-type coupling for both T and P. + All box dimensions are scaled by the same amount, there is no change in the angles between axes. */ -void Velocity_Verlet_Berendsen_SemiIsotropic_NPT( reax_system* system, - control_params* control, - simulation_data *data, - static_storage *workspace, - list **lists, - output_controls *out_control ) +void Velocity_Verlet_Berendsen_SemiIsotropic_NPT( reax_system* system, + control_params* control, + simulation_data *data, + static_storage *workspace, + list **lists, + output_controls *out_control ) { - int i, d, steps, renbr; - real dt, inv_m, lambda; - rvec dx, mu; + int i, d, steps, renbr; + real dt, inv_m, lambda; + rvec dx, mu; - dt = control->dt; - steps = data->step - data->prev_steps; - renbr = (steps % control->reneighbor == 0); + dt = control->dt; + steps = data->step - data->prev_steps; + renbr = (steps % control->reneighbor == 0); #if defined(DEBUG_FOCUS) - //fprintf( out_control->prs, - // "tau_t: %g tau_p: %g dt/tau_t: %g dt/tau_p: %g\n", - //control->Tau_T, control->Tau_P, dt / control->Tau_T, dt / control->Tau_P ); - fprintf( stderr, "step %d: ", data->step ); + //fprintf( out_control->prs, + // "tau_t: %g tau_p: %g dt/tau_t: %g dt/tau_p: %g\n", + //control->Tau_T, control->Tau_P, dt / control->Tau_T, dt / control->Tau_P ); + fprintf( stderr, "step %d: ", data->step ); #endif - /* velocity verlet, 1st part */ - for( i = 0; i < system->N; i++ ) { - inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; - /* Compute x(t + dt) */ - rvec_ScaledSum( dx, dt, system->atoms[i].v, - 0.5 * -F_CONV * inv_m * SQR(dt), system->atoms[i].f ); - Inc_on_T3( system->atoms[i].x, dx, &(system->box) ); - /* Compute v(t + dt/2) */ - rvec_ScaledAdd( system->atoms[i].v, - 0.5 * -F_CONV * inv_m * dt, system->atoms[i].f ); - /*fprintf( stderr, "%6d %15.8f %15.8f %15.8f %15.8f %15.8f %15.8f\n", - workspace->orig_id[i], - system->atoms[i].x[0], system->atoms[i].x[1], system->atoms[i].x[2], - 0.5 * SQR(dt) * -F_CONV * inv_m * system->atoms[i].f[0], - 0.5 * SQR(dt) * -F_CONV * inv_m * system->atoms[i].f[1], - 0.5 * SQR(dt) * -F_CONV * inv_m * system->atoms[i].f[2] ); */ - } + /* velocity verlet, 1st part */ + for ( i = 0; i < system->N; i++ ) + { + inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; + /* Compute x(t + dt) */ + rvec_ScaledSum( dx, dt, system->atoms[i].v, + 0.5 * -F_CONV * inv_m * SQR(dt), system->atoms[i].f ); + Inc_on_T3( system->atoms[i].x, dx, &(system->box) ); + /* Compute v(t + dt/2) */ + rvec_ScaledAdd( system->atoms[i].v, + 0.5 * -F_CONV * inv_m * dt, system->atoms[i].f ); + /*fprintf( stderr, "%6d %15.8f %15.8f %15.8f %15.8f %15.8f %15.8f\n", + workspace->orig_id[i], + system->atoms[i].x[0], system->atoms[i].x[1], system->atoms[i].x[2], + 0.5 * SQR(dt) * -F_CONV * inv_m * system->atoms[i].f[0], + 0.5 * SQR(dt) * -F_CONV * inv_m * system->atoms[i].f[1], + 0.5 * SQR(dt) * -F_CONV * inv_m * system->atoms[i].f[2] ); */ + } #if defined(DEBUG_FOCUS) - fprintf( stderr, "verlet1 - " ); + fprintf( stderr, "verlet1 - " ); #endif - Reallocate( system, workspace, lists, renbr ); - Reset( system, control, data, workspace, lists ); - if( renbr ) { - Update_Grid( system ); - Generate_Neighbor_Lists( system, control, data, workspace, - lists, out_control ); - } - Compute_Forces( system, control, data, workspace, lists, out_control ); - - /* velocity verlet, 2nd part */ - for( i = 0; i < system->N; i++ ) { - inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; - /* Compute v(t + dt) */ - rvec_ScaledAdd( system->atoms[i].v, - 0.5 * dt * -F_CONV * inv_m, system->atoms[i].f ); - /* fprintf( stderr, "%6d %15f %15f %15f %15.8f %15.8f %15.8f\n", - workspace->orig_id[i], - system->atoms[i].v[0], system->atoms[i].v[1], system->atoms[i].v[2], - 0.5 * dt * -F_CONV * inv_m * system->atoms[i].f[0], - 0.5 * dt * -F_CONV * inv_m * system->atoms[i].f[1], - 0.5 * dt * -F_CONV * inv_m * system->atoms[i].f[2] );*/ - } - Compute_Kinetic_Energy( system, data ); - Compute_Pressure_Isotropic( system, control, data, out_control ); -#if defined(DEBUG_FOCUS) - fprintf( stderr, "verlet2 - " ); + Reallocate( system, workspace, lists, renbr ); + Reset( system, control, data, workspace, lists ); + if ( renbr ) + { + Update_Grid( system ); + Generate_Neighbor_Lists( system, control, data, workspace, + lists, out_control ); + } + Compute_Forces( system, control, data, workspace, lists, out_control ); + + /* velocity verlet, 2nd part */ + for ( i = 0; i < system->N; i++ ) + { + inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; + /* Compute v(t + dt) */ + rvec_ScaledAdd( system->atoms[i].v, + 0.5 * dt * -F_CONV * inv_m, system->atoms[i].f ); + /* fprintf( stderr, "%6d %15f %15f %15f %15.8f %15.8f %15.8f\n", + workspace->orig_id[i], + system->atoms[i].v[0], system->atoms[i].v[1], system->atoms[i].v[2], + 0.5 * dt * -F_CONV * inv_m * system->atoms[i].f[0], + 0.5 * dt * -F_CONV * inv_m * system->atoms[i].f[1], + 0.5 * dt * -F_CONV * inv_m * system->atoms[i].f[2] );*/ + } + Compute_Kinetic_Energy( system, data ); + Compute_Pressure_Isotropic( system, control, data, out_control ); +#if defined(DEBUG_FOCUS) + fprintf( stderr, "verlet2 - " ); #endif - /* pressure scaler */ - for( d = 0; d < 3; ++d ){ - mu[d] = POW( 1.0+(dt/control->Tau_P[d])*(data->tot_press[d]-control->P[d]), - 1.0 / 3 ); - if( mu[d] < MIN_dV ) - mu[d] = MIN_dV; - else if( mu[d] > MAX_dV ) - mu[d] = MAX_dV; - } - - /* temperature scaler */ - lambda = 1.0 + (dt / control->Tau_T) * (control->T / data->therm.T - 1.0); - if( lambda < MIN_dT ) - lambda = MIN_dT; - else if (lambda > MAX_dT ) - lambda = MAX_dT; - lambda = SQRT( lambda ); - - /* Scale velocities and positions at t+dt */ - for( i = 0; i < system->N; ++i ) { - rvec_Scale( system->atoms[i].v, lambda, system->atoms[i].v ); - /* IMPORTANT: What Adri does with scaling positions first to - unit coordinates and then back to cartesian coordinates essentially - is scaling the coordinates with mu^2. However, this causes unphysical - modifications on the system because box dimensions - are being scaled with mu! We need to discuss this with Adri! */ - for( d = 0; d < 3; ++d ) - system->atoms[i].x[d] = system->atoms[i].x[d] * mu[d]; - } - Compute_Kinetic_Energy( system, data ); -#if defined(DEBUG_FOCUS) - fprintf( stderr, "scaling - " ); + /* pressure scaler */ + for ( d = 0; d < 3; ++d ) + { + mu[d] = POW( 1.0 + (dt / control->Tau_P[d]) * (data->tot_press[d] - control->P[d]), + 1.0 / 3 ); + if ( mu[d] < MIN_dV ) + mu[d] = MIN_dV; + else if ( mu[d] > MAX_dV ) + mu[d] = MAX_dV; + } + + /* temperature scaler */ + lambda = 1.0 + (dt / control->Tau_T) * (control->T / data->therm.T - 1.0); + if ( lambda < MIN_dT ) + lambda = MIN_dT; + else if (lambda > MAX_dT ) + lambda = MAX_dT; + lambda = SQRT( lambda ); + + /* Scale velocities and positions at t+dt */ + for ( i = 0; i < system->N; ++i ) + { + rvec_Scale( system->atoms[i].v, lambda, system->atoms[i].v ); + /* IMPORTANT: What Adri does with scaling positions first to + unit coordinates and then back to cartesian coordinates essentially + is scaling the coordinates with mu^2. However, this causes unphysical + modifications on the system because box dimensions + are being scaled with mu! We need to discuss this with Adri! */ + for ( d = 0; d < 3; ++d ) + system->atoms[i].x[d] = system->atoms[i].x[d] * mu[d]; + } + Compute_Kinetic_Energy( system, data ); +#if defined(DEBUG_FOCUS) + fprintf( stderr, "scaling - " ); #endif - Update_Box_SemiIsotropic( &(system->box), mu ); -#if defined(DEBUG_FOCUS) - fprintf( stderr, "updated box & grid\n" ); + Update_Box_SemiIsotropic( &(system->box), mu ); +#if defined(DEBUG_FOCUS) + fprintf( stderr, "updated box & grid\n" ); #endif } @@ -425,333 +440,341 @@ void Velocity_Verlet_Berendsen_SemiIsotropic_NPT( reax_system* system, #ifdef ANISOTROPIC -void Velocity_Verlet_Nose_Hoover_NVT(reax_system* system, - control_params* control, - simulation_data *data, - static_storage *workspace, - list **lists, - output_controls *out_control ) +void Velocity_Verlet_Nose_Hoover_NVT(reax_system* system, + control_params* control, + simulation_data *data, + static_storage *workspace, + list **lists, + output_controls *out_control ) { - int i; - real inv_m; - real dt = control->dt; - real dt_sqr = SQR(dt); - rvec dx; + int i; + real inv_m; + real dt = control->dt; + real dt_sqr = SQR(dt); + rvec dx; - for (i=0; i < system->N; i++) + for (i = 0; i < system->N; i++) { - inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; - - // Compute x(t + dt) - rvec_ScaledSum( dx, dt, system->atoms[i].v, - 0.5 * dt_sqr * -F_CONV * inv_m, system->atoms[i].f ); - Inc_on_T3_Gen( system->atoms[i].x, dx, &(system->box) ); - - // Compute v(t + dt/2) - rvec_ScaledAdd( system->atoms[i].v, - -0.5 * dt * data->therm.xi, system->atoms[i].v ); - rvec_ScaledAdd( system->atoms[i].v, - 0.5 * dt * -F_CONV * inv_m, system->atoms[i].f ); + inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; + + // Compute x(t + dt) + rvec_ScaledSum( dx, dt, system->atoms[i].v, + 0.5 * dt_sqr * -F_CONV * inv_m, system->atoms[i].f ); + Inc_on_T3_Gen( system->atoms[i].x, dx, &(system->box) ); + + // Compute v(t + dt/2) + rvec_ScaledAdd( system->atoms[i].v, + -0.5 * dt * data->therm.xi, system->atoms[i].v ); + rvec_ScaledAdd( system->atoms[i].v, + 0.5 * dt * -F_CONV * inv_m, system->atoms[i].f ); } - // Compute zeta(t + dt/2), E_Kininetic(t + dt/2) - // IMPORTANT: What will be the initial value of zeta? and what is g? - data->therm.xi += 0.5 * dt * control->Tau_T * - ( 2.0 * data->E_Kin - data->N_f * K_B * control->T ); + // Compute zeta(t + dt/2), E_Kininetic(t + dt/2) + // IMPORTANT: What will be the initial value of zeta? and what is g? + data->therm.xi += 0.5 * dt * control->Tau_T * + ( 2.0 * data->E_Kin - data->N_f * K_B * control->T ); - Reset( system, control, data, workspace ); - fprintf(out_control->log,"reset-"); fflush( out_control->log ); + Reset( system, control, data, workspace ); + fprintf(out_control->log, "reset-"); + fflush( out_control->log ); - Generate_Neighbor_Lists( system, control, data, workspace, - lists, out_control ); - fprintf(out_control->log,"nbrs-"); fflush( out_control->log ); + Generate_Neighbor_Lists( system, control, data, workspace, + lists, out_control ); + fprintf(out_control->log, "nbrs-"); + fflush( out_control->log ); - /* QEq( system, control, workspace, lists[FAR_NBRS], out_control ); - fprintf(out_control->log,"qeq-"); fflush( out_control->log ); */ + /* QEq( system, control, workspace, lists[FAR_NBRS], out_control ); + fprintf(out_control->log,"qeq-"); fflush( out_control->log ); */ - Compute_Forces( system, control, data, workspace, lists, out_control ); - fprintf(out_control->log,"forces\n"); fflush( out_control->log ); + Compute_Forces( system, control, data, workspace, lists, out_control ); + fprintf(out_control->log, "forces\n"); + fflush( out_control->log ); - Compute_Kinetic_Energy( system, data ); + Compute_Kinetic_Energy( system, data ); - for( i = 0; i < system->N; i++ ) + for ( i = 0; i < system->N; i++ ) { - inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; + inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; - // compute v(t + dt) - rvec_ScaledAdd( system->atoms[i].v, - -0.5 * dt * data->therm.xi, system->atoms[i].v ); - rvec_ScaledAdd( system->atoms[i].v, - 0.5 * dt * -F_CONV * inv_m, system->atoms[i].f ); + // compute v(t + dt) + rvec_ScaledAdd( system->atoms[i].v, + -0.5 * dt * data->therm.xi, system->atoms[i].v ); + rvec_ScaledAdd( system->atoms[i].v, + 0.5 * dt * -F_CONV * inv_m, system->atoms[i].f ); } - - // Compute zeta(t + dt) - data->therm.xi += 0.5*dt * control->Tau_T * ( 2.0 * data->E_Kin - - data->N_f * K_B * control->T ); - - fprintf( out_control->log,"Xi: %8.3f %8.3f %8.3f\n", - data->therm.xi, data->E_Kin, data->N_f * K_B * control->T ); - fflush( out_control->log ); + + // Compute zeta(t + dt) + data->therm.xi += 0.5 * dt * control->Tau_T * ( 2.0 * data->E_Kin - + data->N_f * K_B * control->T ); + + fprintf( out_control->log, "Xi: %8.3f %8.3f %8.3f\n", + data->therm.xi, data->E_Kin, data->N_f * K_B * control->T ); + fflush( out_control->log ); } -void Velocity_Verlet_Isotropic_NPT( reax_system* system, - control_params* control, - simulation_data *data, - static_storage *workspace, - list **lists, - output_controls *out_control ) +void Velocity_Verlet_Isotropic_NPT( reax_system* system, + control_params* control, + simulation_data *data, + static_storage *workspace, + list **lists, + output_controls *out_control ) { - int i, itr; - real deps, v_eps_new=0, v_eps_old=0, G_xi_new; - real dxi, v_xi_new=0, v_xi_old=0, a_eps_new; - real inv_m, exp_deps, inv_3V; - real E_kin, P_int, P_int_const; - real coef_v, coef_v_eps; - real dt = control->dt; - real dt_sqr = SQR( dt ); - thermostat *therm = &( data->therm ); - isotropic_barostat *iso_bar = &( data->iso_bar ); - simulation_box *box = &( system->box ); - rvec dx, dv; - - // Here we just calculate how much to increment eps, xi, v_eps, v_xi. - // Commits are done after positions and velocities of atoms are updated - // because position, velocity updates uses v_eps, v_xi terms; - // yet we need EXP( deps ) to be able to calculate - // positions and velocities accurately. - iso_bar->a_eps = control->Tau_P * - ( 3.0 * box->volume * (iso_bar->P - control->P) + - 6.0 * data->E_Kin / data->N_f ) - iso_bar->v_eps * therm->v_xi; - deps = dt * iso_bar->v_eps + 0.5 * dt_sqr * iso_bar->a_eps; - exp_deps = EXP( deps ); - - therm->G_xi = control->Tau_T * ( 2.0 * data->E_Kin + - SQR( iso_bar->v_eps ) / control->Tau_P - - (data->N_f +1) * K_B * control->T ); - dxi = therm->v_xi * dt + 0.5 * therm->G_xi * dt_sqr; - - fprintf(out_control->log, "a: %12.6f eps: %12.6f deps: %12.6f\n", - iso_bar->a_eps, iso_bar->v_eps, iso_bar->eps); - fprintf(out_control->log, "G: %12.6f xi : %12.6f dxi : %12.6f\n", - therm->G_xi, therm->v_xi, therm->xi ); - - // Update positions and velocities - // NOTE: v_old, v_xi_old, v_eps_old are meant to be the old values - // in the iteration not the old values at time t or before! - for (i=0; i < system->N; i++) + int i, itr; + real deps, v_eps_new = 0, v_eps_old = 0, G_xi_new; + real dxi, v_xi_new = 0, v_xi_old = 0, a_eps_new; + real inv_m, exp_deps, inv_3V; + real E_kin, P_int, P_int_const; + real coef_v, coef_v_eps; + real dt = control->dt; + real dt_sqr = SQR( dt ); + thermostat *therm = &( data->therm ); + isotropic_barostat *iso_bar = &( data->iso_bar ); + simulation_box *box = &( system->box ); + rvec dx, dv; + + // Here we just calculate how much to increment eps, xi, v_eps, v_xi. + // Commits are done after positions and velocities of atoms are updated + // because position, velocity updates uses v_eps, v_xi terms; + // yet we need EXP( deps ) to be able to calculate + // positions and velocities accurately. + iso_bar->a_eps = control->Tau_P * + ( 3.0 * box->volume * (iso_bar->P - control->P) + + 6.0 * data->E_Kin / data->N_f ) - iso_bar->v_eps * therm->v_xi; + deps = dt * iso_bar->v_eps + 0.5 * dt_sqr * iso_bar->a_eps; + exp_deps = EXP( deps ); + + therm->G_xi = control->Tau_T * ( 2.0 * data->E_Kin + + SQR( iso_bar->v_eps ) / control->Tau_P - + (data->N_f + 1) * K_B * control->T ); + dxi = therm->v_xi * dt + 0.5 * therm->G_xi * dt_sqr; + + fprintf(out_control->log, "a: %12.6f eps: %12.6f deps: %12.6f\n", + iso_bar->a_eps, iso_bar->v_eps, iso_bar->eps); + fprintf(out_control->log, "G: %12.6f xi : %12.6f dxi : %12.6f\n", + therm->G_xi, therm->v_xi, therm->xi ); + + // Update positions and velocities + // NOTE: v_old, v_xi_old, v_eps_old are meant to be the old values + // in the iteration not the old values at time t or before! + for (i = 0; i < system->N; i++) { - inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; - - // Compute x(t + dt) - rvec_ScaledSum( workspace->a[i], -F_CONV * inv_m, system->atoms[i].f, - -( (2.0 + 3.0/data->N_f) * iso_bar->v_eps + therm->v_xi ), - system->atoms[i].v ); - rvec_ScaledSum( dx, dt, system->atoms[i].v, - 0.5 * dt_sqr, workspace->a[i] ); - Inc_on_T3( system->atoms[i].x, dx, &(system->box) ); - rvec_Scale( system->atoms[i].x, exp_deps, system->atoms[i].x ); + inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; + + // Compute x(t + dt) + rvec_ScaledSum( workspace->a[i], -F_CONV * inv_m, system->atoms[i].f, + -( (2.0 + 3.0 / data->N_f) * iso_bar->v_eps + therm->v_xi ), + system->atoms[i].v ); + rvec_ScaledSum( dx, dt, system->atoms[i].v, + 0.5 * dt_sqr, workspace->a[i] ); + Inc_on_T3( system->atoms[i].x, dx, &(system->box) ); + rvec_Scale( system->atoms[i].x, exp_deps, system->atoms[i].x ); } - // Commit updates - therm->xi += dxi; - iso_bar->eps += deps; - //Update_Box_Isotropic( EXP( 3.0 * iso_bar->eps ), &(system->box) ); - Update_Box_Isotropic( &(system->box), EXP( 3.0 * iso_bar->eps ) ); + // Commit updates + therm->xi += dxi; + iso_bar->eps += deps; + //Update_Box_Isotropic( EXP( 3.0 * iso_bar->eps ), &(system->box) ); + Update_Box_Isotropic( &(system->box), EXP( 3.0 * iso_bar->eps ) ); - // Calculate new forces, f(t + dt) - Reset( system, control, data, workspace ); - fprintf(out_control->log,"reset-"); fflush( out_control->log ); + // Calculate new forces, f(t + dt) + Reset( system, control, data, workspace ); + fprintf(out_control->log, "reset-"); + fflush( out_control->log ); - Generate_Neighbor_Lists( system, control, data, workspace, - lists, out_control ); - fprintf(out_control->log,"nbrs-"); fflush( out_control->log ); + Generate_Neighbor_Lists( system, control, data, workspace, + lists, out_control ); + fprintf(out_control->log, "nbrs-"); + fflush( out_control->log ); - /* QEq( system, control, workspace, lists[FAR_NBRS], out_control ); - fprintf(out_control->log,"qeq-"); fflush( out_control->log ); */ + /* QEq( system, control, workspace, lists[FAR_NBRS], out_control ); + fprintf(out_control->log,"qeq-"); fflush( out_control->log ); */ - Compute_Forces( system, control, data, workspace, lists, out_control ); - fprintf(out_control->log,"forces\n"); fflush( out_control->log ); + Compute_Forces( system, control, data, workspace, lists, out_control ); + fprintf(out_control->log, "forces\n"); + fflush( out_control->log ); - // Compute iteration constants for each atom's velocity and for P_internal - // Compute kinetic energy for initial velocities of the iteration - P_int_const = E_kin = 0; - for( i = 0; i < system->N; ++i ) + // Compute iteration constants for each atom's velocity and for P_internal + // Compute kinetic energy for initial velocities of the iteration + P_int_const = E_kin = 0; + for ( i = 0; i < system->N; ++i ) { - inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; + inv_m = 1.0 / system->reaxprm.sbp[system->atoms[i].type].mass; - rvec_ScaledSum( dv, 0.5 * dt, workspace->a[i], - 0.5 * dt * -F_CONV * inv_m, system->atoms[i].f ); - rvec_Add( dv, system->atoms[i].v ); - rvec_Scale( workspace->v_const[i], exp_deps, dv ); + rvec_ScaledSum( dv, 0.5 * dt, workspace->a[i], + 0.5 * dt * -F_CONV * inv_m, system->atoms[i].f ); + rvec_Add( dv, system->atoms[i].v ); + rvec_Scale( workspace->v_const[i], exp_deps, dv ); - P_int_const += ( -F_CONV * - rvec_Dot( system->atoms[i].f, system->atoms[i].x ) ); + P_int_const += ( -F_CONV * + rvec_Dot( system->atoms[i].f, system->atoms[i].x ) ); - E_kin += (0.5 * system->reaxprm.sbp[system->atoms[i].type].mass * - rvec_Dot( system->atoms[i].v, system->atoms[i].v ) ); + E_kin += (0.5 * system->reaxprm.sbp[system->atoms[i].type].mass * + rvec_Dot( system->atoms[i].v, system->atoms[i].v ) ); } - - // Compute initial p_int - inv_3V = 1.0 / (3.0 * system->box.volume); - P_int = inv_3V * ( 2.0 * E_kin + P_int_const ); - v_xi_new = therm->v_xi_old + 2.0 * dt * therm->G_xi; - v_eps_new = iso_bar->v_eps_old + 2.0 * dt * iso_bar->a_eps; + // Compute initial p_int + inv_3V = 1.0 / (3.0 * system->box.volume); + P_int = inv_3V * ( 2.0 * E_kin + P_int_const ); + + v_xi_new = therm->v_xi_old + 2.0 * dt * therm->G_xi; + v_eps_new = iso_bar->v_eps_old + 2.0 * dt * iso_bar->a_eps; - itr = 0; - do + itr = 0; + do { - itr++; - // new values become old in this iteration - v_xi_old = v_xi_new; - v_eps_old = v_eps_new; + itr++; + // new values become old in this iteration + v_xi_old = v_xi_new; + v_eps_old = v_eps_new; - for( i = 0; i < system->N; ++i ) - { - coef_v = 1.0 / (1.0 + 0.5 * dt * exp_deps * - ( (2.0 + 3.0/data->N_f) * v_eps_old + v_xi_old ) ); - rvec_Scale( system->atoms[i].v, coef_v, workspace->v_const[i] ); - } - + for ( i = 0; i < system->N; ++i ) + { + coef_v = 1.0 / (1.0 + 0.5 * dt * exp_deps * + ( (2.0 + 3.0 / data->N_f) * v_eps_old + v_xi_old ) ); + rvec_Scale( system->atoms[i].v, coef_v, workspace->v_const[i] ); + } - coef_v_eps = 1.0 / (1.0 + 0.5 * dt * v_xi_old); - a_eps_new = 3.0 * control->Tau_P * - ( system->box.volume * (P_int - control->P) + 2.0 * E_kin / data->N_f ); - v_eps_new = coef_v_eps * ( iso_bar->v_eps + - 0.5 * dt * ( iso_bar->a_eps + a_eps_new ) ); + coef_v_eps = 1.0 / (1.0 + 0.5 * dt * v_xi_old); + a_eps_new = 3.0 * control->Tau_P * + ( system->box.volume * (P_int - control->P) + 2.0 * E_kin / data->N_f ); + v_eps_new = coef_v_eps * ( iso_bar->v_eps + + 0.5 * dt * ( iso_bar->a_eps + a_eps_new ) ); - G_xi_new = control->Tau_T * ( 2.0 * E_kin + - SQR( v_eps_old ) / control->Tau_P - - (data->N_f + 1) * K_B * control->T ); - v_xi_new = therm->v_xi + 0.5 * dt * ( therm->G_xi + G_xi_new ); - - E_kin = 0; - for( i = 0; i < system->N; ++i ) - E_kin += (0.5 * system->reaxprm.sbp[system->atoms[i].type].mass * - rvec_Dot( system->atoms[i].v, system->atoms[i].v ) ); + G_xi_new = control->Tau_T * ( 2.0 * E_kin + + SQR( v_eps_old ) / control->Tau_P - + (data->N_f + 1) * K_B * control->T ); + v_xi_new = therm->v_xi + 0.5 * dt * ( therm->G_xi + G_xi_new ); - P_int = inv_3V * ( 2.0*E_kin + P_int_const ); + E_kin = 0; + for ( i = 0; i < system->N; ++i ) + E_kin += (0.5 * system->reaxprm.sbp[system->atoms[i].type].mass * + rvec_Dot( system->atoms[i].v, system->atoms[i].v ) ); - fprintf( out_control->log, - "itr %d E_kin: %8.3f veps_n:%8.3f veps_o:%8.3f vxi_n:%8.3f vxi_o: %8.3f\n", - itr, E_kin, v_eps_new, v_eps_old, v_xi_new, v_xi_old ); + P_int = inv_3V * ( 2.0 * E_kin + P_int_const ); + + + fprintf( out_control->log, + "itr %d E_kin: %8.3f veps_n:%8.3f veps_o:%8.3f vxi_n:%8.3f vxi_o: %8.3f\n", + itr, E_kin, v_eps_new, v_eps_old, v_xi_new, v_xi_old ); } - while( fabs(v_eps_new - v_eps_old) + fabs(v_xi_new - v_xi_old) > 2e-3 ); + while ( fabs(v_eps_new - v_eps_old) + fabs(v_xi_new - v_xi_old) > 2e-3 ); - therm->v_xi_old = therm->v_xi; - therm->v_xi = v_xi_new; - therm->G_xi = G_xi_new; + therm->v_xi_old = therm->v_xi; + therm->v_xi = v_xi_new; + therm->G_xi = G_xi_new; - iso_bar->v_eps_old = iso_bar->v_eps; - iso_bar->v_eps = v_eps_new; - iso_bar->a_eps = a_eps_new; + iso_bar->v_eps_old = iso_bar->v_eps; + iso_bar->v_eps = v_eps_new; + iso_bar->a_eps = a_eps_new; - fprintf( out_control->log, "V: %8.3ff\tsides{%8.3f, %8.3f, %8.3f}\n", - system->box.volume, - system->box.box[0][0],system->box.box[1][1],system->box.box[2][2] ); - fprintf(out_control->log,"eps:\ta- %8.3f v- %8.3f eps- %8.3f\n", - iso_bar->a_eps, iso_bar->v_eps, iso_bar->eps); - fprintf(out_control->log,"xi: \tG- %8.3f v- %8.3f xi - %8.3f\n", - therm->G_xi, therm->v_xi, therm->xi); + fprintf( out_control->log, "V: %8.3ff\tsides{%8.3f, %8.3f, %8.3f}\n", + system->box.volume, + system->box.box[0][0], system->box.box[1][1], system->box.box[2][2] ); + fprintf(out_control->log, "eps:\ta- %8.3f v- %8.3f eps- %8.3f\n", + iso_bar->a_eps, iso_bar->v_eps, iso_bar->eps); + fprintf(out_control->log, "xi: \tG- %8.3f v- %8.3f xi - %8.3f\n", + therm->G_xi, therm->v_xi, therm->xi); } #endif -/* uses Berendsen-type coupling for both T and P. - All box dimensions are scaled by the same amount, +/* uses Berendsen-type coupling for both T and P. + All box dimensions are scaled by the same amount, there is no change in the angles between axes. */ -void Velocity_Verlet_Berendsen_NVT( reax_system* system, - control_params* control, - simulation_data *data, - static_storage *workspace, - list **lists, - output_controls *out_control - ) +void Velocity_Verlet_Berendsen_NVT( reax_system* system, + control_params* control, + simulation_data *data, + static_storage *workspace, + list **lists, + output_controls *out_control + ) { - int i, steps, renbr; - real inv_m, dt, lambda; - rvec dx; - reax_atom *atom; + int i, steps, renbr; + real inv_m, dt, lambda; + rvec dx; + reax_atom *atom; #if defined(DEBUG_FOCUS) - fprintf( stderr, "step%d\n", data->step ); -#endif - dt = control->dt; - steps = data->step - data->prev_steps; - renbr = (steps % control->reneighbor == 0); - - /* velocity verlet, 1st part */ - for( i = 0; i < system->N; i++ ) { - atom = &(system->atoms[i]); - inv_m = 1.0 / system->reaxprm.sbp[atom->type].mass; - /* Compute x(t + dt) */ - rvec_ScaledSum( dx, dt, atom->v, 0.5 * -F_CONV * inv_m * SQR(dt), atom->f ); - - /* bNVT fix - Metin's suggestion */ - /* ORIGINAL CHANGE -- CHECK THE branch serial-bnvt for the fix */ - //rvec_Add( atom->x, dx ); - Inc_on_T3( atom->x, dx, &( system->box ) ); - - /* Compute v(t + dt/2) */ - rvec_ScaledAdd( atom->v, 0.5 * -F_CONV * inv_m * dt, atom->f ); - } + fprintf( stderr, "step%d\n", data->step ); +#endif + dt = control->dt; + steps = data->step - data->prev_steps; + renbr = (steps % control->reneighbor == 0); + + /* velocity verlet, 1st part */ + for ( i = 0; i < system->N; i++ ) + { + atom = &(system->atoms[i]); + inv_m = 1.0 / system->reaxprm.sbp[atom->type].mass; + /* Compute x(t + dt) */ + rvec_ScaledSum( dx, dt, atom->v, 0.5 * -F_CONV * inv_m * SQR(dt), atom->f ); + + /* bNVT fix - Metin's suggestion */ + /* ORIGINAL CHANGE -- CHECK THE branch serial-bnvt for the fix */ + //rvec_Add( atom->x, dx ); + Inc_on_T3( atom->x, dx, &( system->box ) ); + + /* Compute v(t + dt/2) */ + rvec_ScaledAdd( atom->v, 0.5 * -F_CONV * inv_m * dt, atom->f ); + } #if defined(DEBUG_FOCUS) - fprintf(stderr, "step%d: verlet1 done\n", data->step); -#endif - - Reallocate( system, workspace, lists, renbr ); - Reset( system, control, data, workspace, lists ); - - if( renbr ) - Generate_Neighbor_Lists( system, control, data, workspace, lists, out_control ); - - Compute_Forces( system, control, data, workspace, - lists, out_control ); - - /* velocity verlet, 2nd part */ - for( i = 0; i < system->N; i++ ) { - atom = &(system->atoms[i]); - inv_m = 1.0 / system->reaxprm.sbp[atom->type].mass; - /* Compute v(t + dt) */ - rvec_ScaledAdd( atom->v, 0.5 * dt * -F_CONV * inv_m, atom->f ); - } -#if defined(DEBUG_FOCUS) - fprintf(stderr, "step%d: verlet2 done\n", data->step); + fprintf(stderr, "step%d: verlet1 done\n", data->step); #endif - /* temperature scaler */ - Compute_Kinetic_Energy( system, data ); - lambda = 1.0 + (dt / control->Tau_T) * (control->T / data->therm.T - 1.0); - if( lambda < MIN_dT ) - lambda = MIN_dT; - else if (lambda > MAX_dT ) - lambda = MAX_dT; - lambda = SQRT( lambda ); - - fprintf (stderr, "step:%d lambda -> %f \n", data->step, lambda); - - /* Scale velocities and positions at t+dt */ - for( i = 0; i < system->N; ++i ) { - atom = &(system->atoms[i]); - rvec_Scale( atom->v, lambda, atom->v ); - } - Compute_Kinetic_Energy( system, data ); - -#if defined(DEBUG_FOCUS) - fprintf( stderr, "step%d: scaled velocities\n", - data->step ); + Reallocate( system, workspace, lists, renbr ); + Reset( system, control, data, workspace, lists ); + + if ( renbr ) + Generate_Neighbor_Lists( system, control, data, workspace, lists, out_control ); + + Compute_Forces( system, control, data, workspace, + lists, out_control ); + + /* velocity verlet, 2nd part */ + for ( i = 0; i < system->N; i++ ) + { + atom = &(system->atoms[i]); + inv_m = 1.0 / system->reaxprm.sbp[atom->type].mass; + /* Compute v(t + dt) */ + rvec_ScaledAdd( atom->v, 0.5 * dt * -F_CONV * inv_m, atom->f ); + } +#if defined(DEBUG_FOCUS) + fprintf(stderr, "step%d: verlet2 done\n", data->step); #endif -} + /* temperature scaler */ + Compute_Kinetic_Energy( system, data ); + lambda = 1.0 + (dt / control->Tau_T) * (control->T / data->therm.T - 1.0); + if ( lambda < MIN_dT ) + lambda = MIN_dT; + else if (lambda > MAX_dT ) + lambda = MAX_dT; + lambda = SQRT( lambda ); + + fprintf (stderr, "step:%d lambda -> %f \n", data->step, lambda); + + /* Scale velocities and positions at t+dt */ + for ( i = 0; i < system->N; ++i ) + { + atom = &(system->atoms[i]); + rvec_Scale( atom->v, lambda, atom->v ); + } + Compute_Kinetic_Energy( system, data ); + +#if defined(DEBUG_FOCUS) + fprintf( stderr, "step%d: scaled velocities\n", + data->step ); +#endif +} diff --git a/puremd_rc_1003/sPuReMD/integrate.h b/puremd_rc_1003/sPuReMD/integrate.h index 8baee8ba..55d98786 100644 --- a/puremd_rc_1003/sPuReMD/integrate.h +++ b/puremd_rc_1003/sPuReMD/integrate.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -25,33 +25,33 @@ #include "mytypes.h" void Velocity_Verlet_NVE( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); -void Velocity_Verlet_Nose_Hoover_NVT( reax_system*, control_params*, - simulation_data*, static_storage*, - list**, output_controls* ); -void Velocity_Verlet_Nose_Hoover_NVT_Klein( reax_system*, control_params*, - simulation_data*, static_storage*, - list**, output_controls* ); -void Velocity_Verlet_Flexible_NPT( reax_system*, control_params*, - simulation_data*,static_storage*, - list**, output_controls* ); -void Velocity_Verlet_Isotropic_NPT( reax_system*, control_params*, - simulation_data*, static_storage*, - list**, output_controls* ); -void Velocity_Verlet_Berendsen_Isotropic_NPT( reax_system*, control_params*, - simulation_data*, static_storage*, - list**, output_controls* ); + static_storage*, list**, output_controls* ); +void Velocity_Verlet_Nose_Hoover_NVT( reax_system*, control_params*, + simulation_data*, static_storage*, + list**, output_controls* ); +void Velocity_Verlet_Nose_Hoover_NVT_Klein( reax_system*, control_params*, + simulation_data*, static_storage*, + list**, output_controls* ); +void Velocity_Verlet_Flexible_NPT( reax_system*, control_params*, + simulation_data*, static_storage*, + list**, output_controls* ); +void Velocity_Verlet_Isotropic_NPT( reax_system*, control_params*, + simulation_data*, static_storage*, + list**, output_controls* ); +void Velocity_Verlet_Berendsen_Isotropic_NPT( reax_system*, control_params*, + simulation_data*, static_storage*, + list**, output_controls* ); void Velocity_Verlet_Berendsen_SemiIsotropic_NPT( reax_system*, control_params*, - simulation_data*, - static_storage*, list**, - output_controls* ); + simulation_data*, + static_storage*, list**, + output_controls* ); //upon Adri's request moved from parallel code to serial code -void Velocity_Verlet_Berendsen_NVT( reax_system* , - control_params* , - simulation_data *, - static_storage *, - list **, - output_controls * - ); +void Velocity_Verlet_Berendsen_NVT( reax_system* , + control_params* , + simulation_data *, + static_storage *, + list **, + output_controls * + ); #endif diff --git a/puremd_rc_1003/sPuReMD/list.c b/puremd_rc_1003/sPuReMD/list.c index 01d4fb80..f9044a6c 100644 --- a/puremd_rc_1003/sPuReMD/list.c +++ b/puremd_rc_1003/sPuReMD/list.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -23,147 +23,147 @@ char Make_List(int n, int num_intrs, int type, list* l) { - char success=1; - - l->n = n; - l->num_intrs = num_intrs; - - l->index = (int*) malloc( n * sizeof(int) ); - l->end_index = (int*) malloc( n * sizeof(int) ); - - if (l->index == NULL) success = 0; - if (l->end_index == NULL) success = 0; - - switch(type) + char success = 1; + + l->n = n; + l->num_intrs = num_intrs; + + l->index = (int*) malloc( n * sizeof(int) ); + l->end_index = (int*) malloc( n * sizeof(int) ); + + if (l->index == NULL) success = 0; + if (l->end_index == NULL) success = 0; + + switch (type) { case TYP_VOID: - l->select.v = (void *) malloc(l->num_intrs*sizeof(void)); - if (l->select.v == NULL) success = 0; - break; + l->select.v = (void *) malloc(l->num_intrs * sizeof(void)); + if (l->select.v == NULL) success = 0; + break; case TYP_THREE_BODY: - l->select.three_body_list = (three_body_interaction_data*) - malloc(l->num_intrs*sizeof(three_body_interaction_data)); - if (l->select.three_body_list == NULL) success = 0; - break; + l->select.three_body_list = (three_body_interaction_data*) + malloc(l->num_intrs * sizeof(three_body_interaction_data)); + if (l->select.three_body_list == NULL) success = 0; + break; case TYP_BOND: - l->select.bond_list = (bond_data*) - malloc(l->num_intrs * sizeof(bond_data)); - if (l->select.bond_list == NULL) success = 0; - break; + l->select.bond_list = (bond_data*) + malloc(l->num_intrs * sizeof(bond_data)); + if (l->select.bond_list == NULL) success = 0; + break; case TYP_DBO: - l->select.dbo_list = (dbond_data*) - malloc(l->num_intrs * sizeof(dbond_data)); - if (l->select.dbo_list == NULL) success = 0; - break; + l->select.dbo_list = (dbond_data*) + malloc(l->num_intrs * sizeof(dbond_data)); + if (l->select.dbo_list == NULL) success = 0; + break; case TYP_DDELTA: - l->select.dDelta_list = (dDelta_data*) - malloc(l->num_intrs*sizeof(dDelta_data)); - if (l->select.dDelta_list == NULL) success = 0; - break; + l->select.dDelta_list = (dDelta_data*) + malloc(l->num_intrs * sizeof(dDelta_data)); + if (l->select.dDelta_list == NULL) success = 0; + break; case TYP_FAR_NEIGHBOR: - l->select.far_nbr_list = (far_neighbor_data*) - malloc(l->num_intrs*sizeof(far_neighbor_data)); - if (l->select.far_nbr_list == NULL) success = 0; - break; + l->select.far_nbr_list = (far_neighbor_data*) + malloc(l->num_intrs * sizeof(far_neighbor_data)); + if (l->select.far_nbr_list == NULL) success = 0; + break; case TYP_NEAR_NEIGHBOR: - l->select.near_nbr_list = (near_neighbor_data*) - malloc(l->num_intrs*sizeof(near_neighbor_data)); - if (l->select.near_nbr_list == NULL) success = 0; - break; + l->select.near_nbr_list = (near_neighbor_data*) + malloc(l->num_intrs * sizeof(near_neighbor_data)); + if (l->select.near_nbr_list == NULL) success = 0; + break; case TYP_HBOND: - l->select.hbond_list = (hbond_data*) - malloc( l->num_intrs * sizeof(hbond_data) ); - if (l->select.hbond_list == NULL) success = 0; - break; - + l->select.hbond_list = (hbond_data*) + malloc( l->num_intrs * sizeof(hbond_data) ); + if (l->select.hbond_list == NULL) success = 0; + break; + default: - l->select.v = (void *) malloc(l->num_intrs*sizeof(void)); - if (l->select.v == NULL) success = 0; - l->type = TYP_VOID; - break; + l->select.v = (void *) malloc(l->num_intrs * sizeof(void)); + if (l->select.v == NULL) success = 0; + l->type = TYP_VOID; + break; } - return success; + return success; } void Delete_List(list* l) { - if( l->index != NULL ) - free(l->index); - if( l->end_index != NULL ) - free(l->end_index); + if ( l->index != NULL ) + free(l->index); + if ( l->end_index != NULL ) + free(l->end_index); - switch(l->type) + switch (l->type) { case TYP_VOID: - if( l->select.v != NULL ) - free(l->select.v); - break; + if ( l->select.v != NULL ) + free(l->select.v); + break; case TYP_THREE_BODY: - if( l->select.three_body_list != NULL ) - free(l->select.three_body_list); - break; + if ( l->select.three_body_list != NULL ) + free(l->select.three_body_list); + break; case TYP_BOND: - if( l->select.bond_list != NULL ) - free(l->select.bond_list); - break; + if ( l->select.bond_list != NULL ) + free(l->select.bond_list); + break; case TYP_DBO: - if( l->select.dbo_list != NULL ) - free(l->select.dbo_list); - break; + if ( l->select.dbo_list != NULL ) + free(l->select.dbo_list); + break; case TYP_DDELTA: - if( l->select.dDelta_list != NULL ) - free(l->select.dDelta_list); - break; + if ( l->select.dDelta_list != NULL ) + free(l->select.dDelta_list); + break; case TYP_FAR_NEIGHBOR: - if( l->select.far_nbr_list != NULL ) - free(l->select.far_nbr_list); - break; + if ( l->select.far_nbr_list != NULL ) + free(l->select.far_nbr_list); + break; case TYP_NEAR_NEIGHBOR: - if( l->select.near_nbr_list != NULL ) - free(l->select.near_nbr_list); - break; + if ( l->select.near_nbr_list != NULL ) + free(l->select.near_nbr_list); + break; case TYP_HBOND: - if( l->select.hbond_list != NULL ) - free(l->select.hbond_list); - break; - + if ( l->select.hbond_list != NULL ) + free(l->select.hbond_list); + break; + default: - // Report fatal error - break; + // Report fatal error + break; } - + } inline int Num_Entries(int i, list* l) { - return l->end_index[i] - l->index[i]; + return l->end_index[i] - l->index[i]; } inline int Start_Index(int i, list *l ) { - return l->index[i]; + return l->index[i]; } inline int End_Index( int i, list *l ) { - return l->end_index[i]; + return l->end_index[i]; } inline void Set_Start_Index(int i, int val, list *l) { - l->index[i] = val; + l->index[i] = val; } inline void Set_End_Index(int i, int val, list *l) { - l->end_index[i] = val; + l->end_index[i] = val; } diff --git a/puremd_rc_1003/sPuReMD/list.h b/puremd_rc_1003/sPuReMD/list.h index 4b8a726b..e3ecc584 100644 --- a/puremd_rc_1003/sPuReMD/list.h +++ b/puremd_rc_1003/sPuReMD/list.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SeriallReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -27,11 +27,11 @@ char Make_List( int, int, int, list* ); void Delete_List( list* ); -int Num_Entries(int,list*); +int Num_Entries(int, list*); int Start_Index( int, list* ); int End_Index( int, list* ); -void Set_Start_Index(int,int,list*); -void Set_End_Index(int,int,list*); +void Set_Start_Index(int, int, list*); +void Set_End_Index(int, int, list*); #endif diff --git a/puremd_rc_1003/sPuReMD/lookup.c b/puremd_rc_1003/sPuReMD/lookup.c index f4634a21..62ca75ec 100644 --- a/puremd_rc_1003/sPuReMD/lookup.c +++ b/puremd_rc_1003/sPuReMD/lookup.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -23,384 +23,391 @@ #include "two_body_interactions.h" void Make_Lookup_Table(real xmin, real xmax, int n, - lookup_function f, lookup_table* t) + lookup_function f, lookup_table* t) { - int i; - - t->xmin = xmin; - t->xmax = xmax; - t->n = n; - t->dx = (xmax - xmin)/(n-1); - t->inv_dx = 1.0 / t->dx; - t->a = (n-1)/(xmax-xmin); - t->y = (real*) malloc(n*sizeof(real)); - - for(i=0; i < n; i++) - t->y[i] = f(i*t->dx + t->xmin); - - // fprintf(stdout,"dx = %lf\n",t->dx); - // for(i=0; i < n; i++) - // fprintf( stdout,"%d %lf %lf %lf\n", - // i, i/t->a+t->xmin, t->y[i], exp(i/t->a+t->xmin) ); + int i; + + t->xmin = xmin; + t->xmax = xmax; + t->n = n; + t->dx = (xmax - xmin) / (n - 1); + t->inv_dx = 1.0 / t->dx; + t->a = (n - 1) / (xmax - xmin); + t->y = (real*) malloc(n * sizeof(real)); + + for (i = 0; i < n; i++) + t->y[i] = f(i * t->dx + t->xmin); + + // fprintf(stdout,"dx = %lf\n",t->dx); + // for(i=0; i < n; i++) + // fprintf( stdout,"%d %lf %lf %lf\n", + // i, i/t->a+t->xmin, t->y[i], exp(i/t->a+t->xmin) ); } /* Fills solution into x. Warning: will modify c and d! */ -void Tridiagonal_Solve( const real *a, const real *b, - real *c, real *d, real *x, unsigned int n){ - int i; - real id; - - /* Modify the coefficients. */ - c[0] /= b[0]; /* Division by zero risk. */ - d[0] /= b[0]; /* Division by zero would imply a singular matrix. */ - for(i = 1; i < n; i++){ - id = (b[i] - c[i-1] * a[i]); /* Division by zero risk. */ - c[i] /= id; /* Last value calculated is redundant. */ - d[i] = (d[i] - d[i-1] * a[i])/id; - } - - /* Now back substitute. */ - x[n - 1] = d[n - 1]; - for(i = n - 2; i >= 0; i--) - x[i] = d[i] - c[i] * x[i + 1]; +void Tridiagonal_Solve( const real *a, const real *b, + real *c, real *d, real *x, unsigned int n) +{ + int i; + real id; + + /* Modify the coefficients. */ + c[0] /= b[0]; /* Division by zero risk. */ + d[0] /= b[0]; /* Division by zero would imply a singular matrix. */ + for (i = 1; i < n; i++) + { + id = (b[i] - c[i - 1] * a[i]); /* Division by zero risk. */ + c[i] /= id; /* Last value calculated is redundant. */ + d[i] = (d[i] - d[i - 1] * a[i]) / id; + } + + /* Now back substitute. */ + x[n - 1] = d[n - 1]; + for (i = n - 2; i >= 0; i--) + x[i] = d[i] - c[i] * x[i + 1]; } -void Natural_Cubic_Spline( const real *h, const real *f, - cubic_spline_coef *coef, unsigned int n ) +void Natural_Cubic_Spline( const real *h, const real *f, + cubic_spline_coef *coef, unsigned int n ) { - int i; - real *a, *b, *c, *d, *v; - - /* allocate space for the linear system */ - a = (real*) malloc( n * sizeof(real) ); - b = (real*) malloc( n * sizeof(real) ); - c = (real*) malloc( n * sizeof(real) ); - d = (real*) malloc( n * sizeof(real) ); - v = (real*) malloc( n * sizeof(real) ); - - /* build the linear system */ - a[0] = a[1] = a[n-1] = 0; - for( i = 2; i < n-1; ++i ) - a[i] = h[i-1]; - - b[0] = b[n-1] = 0; - for( i = 1; i < n-1; ++i ) - b[i] = 2 * (h[i-1] + h[i]); - - c[0] = c[n-2] = c[n-1] = 0; - for( i = 1; i < n-2; ++i ) - c[i] = h[i]; - - d[0] = d[n-1] = 0; - for( i = 1; i < n-1; ++i ) - d[i] = 6 * ((f[i+1]-f[i])/h[i] - (f[i]-f[i-1])/h[i-1]); - - /*fprintf( stderr, "i a b c d\n" ); - for( i = 0; i < n; ++i ) - fprintf( stderr, "%d %f %f %f %f\n", i, a[i], b[i], c[i], d[i] );*/ - v[0] = 0; - v[n-1] = 0; - Tridiagonal_Solve( &(a[1]), &(b[1]), &(c[1]), &(d[1]), &(v[1]), n-2 ); - - for( i = 1; i < n; ++i ){ - coef[i-1].d = (v[i] - v[i-1]) / (6*h[i-1]); - coef[i-1].c = v[i]/2; - coef[i-1].b = (f[i]-f[i-1])/h[i-1] + h[i-1]*(2*v[i] + v[i-1])/6; - coef[i-1].a = f[i]; - } - - /*fprintf( stderr, "i v coef\n" ); - for( i = 0; i < n; ++i ) - fprintf( stderr, "%d %f %f %f %f %f\n", - i, v[i], coef[i].a, coef[i].b, coef[i].c, coef[i].d ); */ + int i; + real *a, *b, *c, *d, *v; + + /* allocate space for the linear system */ + a = (real*) malloc( n * sizeof(real) ); + b = (real*) malloc( n * sizeof(real) ); + c = (real*) malloc( n * sizeof(real) ); + d = (real*) malloc( n * sizeof(real) ); + v = (real*) malloc( n * sizeof(real) ); + + /* build the linear system */ + a[0] = a[1] = a[n - 1] = 0; + for ( i = 2; i < n - 1; ++i ) + a[i] = h[i - 1]; + + b[0] = b[n - 1] = 0; + for ( i = 1; i < n - 1; ++i ) + b[i] = 2 * (h[i - 1] + h[i]); + + c[0] = c[n - 2] = c[n - 1] = 0; + for ( i = 1; i < n - 2; ++i ) + c[i] = h[i]; + + d[0] = d[n - 1] = 0; + for ( i = 1; i < n - 1; ++i ) + d[i] = 6 * ((f[i + 1] - f[i]) / h[i] - (f[i] - f[i - 1]) / h[i - 1]); + + /*fprintf( stderr, "i a b c d\n" ); + for( i = 0; i < n; ++i ) + fprintf( stderr, "%d %f %f %f %f\n", i, a[i], b[i], c[i], d[i] );*/ + v[0] = 0; + v[n - 1] = 0; + Tridiagonal_Solve( &(a[1]), &(b[1]), &(c[1]), &(d[1]), &(v[1]), n - 2 ); + + for ( i = 1; i < n; ++i ) + { + coef[i - 1].d = (v[i] - v[i - 1]) / (6 * h[i - 1]); + coef[i - 1].c = v[i] / 2; + coef[i - 1].b = (f[i] - f[i - 1]) / h[i - 1] + h[i - 1] * (2 * v[i] + v[i - 1]) / 6; + coef[i - 1].a = f[i]; + } + + /*fprintf( stderr, "i v coef\n" ); + for( i = 0; i < n; ++i ) + fprintf( stderr, "%d %f %f %f %f %f\n", + i, v[i], coef[i].a, coef[i].b, coef[i].c, coef[i].d ); */ } void Complete_Cubic_Spline( const real *h, const real *f, real v0, real vlast, - cubic_spline_coef *coef, unsigned int n ) + cubic_spline_coef *coef, unsigned int n ) { - int i; - real *a, *b, *c, *d, *v; - - /* allocate space for the linear system */ - a = (real*) malloc( n * sizeof(real) ); - b = (real*) malloc( n * sizeof(real) ); - c = (real*) malloc( n * sizeof(real) ); - d = (real*) malloc( n * sizeof(real) ); - v = (real*) malloc( n * sizeof(real) ); - - /* build the linear system */ - a[0] = 0; - for( i = 1; i < n; ++i ) - a[i] = h[i-1]; - - b[0] = 2*h[0]; - for( i = 1; i < n; ++i ) - b[i] = 2 * (h[i-1] + h[i]); - - c[n-1] = 0; - for( i = 0; i < n-1; ++i ) - c[i] = h[i]; - - d[0] = 6 * (f[1]-f[0])/h[0] - 6 * v0; - d[n-1] = 6 * vlast - 6 * (f[n-1]-f[n-2]/h[n-2]); - for( i = 1; i < n-1; ++i ) - d[i] = 6 * ((f[i+1]-f[i])/h[i] - (f[i]-f[i-1])/h[i-1]); - - /*fprintf( stderr, "i a b c d\n" ); - for( i = 0; i < n; ++i ) - fprintf( stderr, "%d %f %f %f %f\n", i, a[i], b[i], c[i], d[i] );*/ - Tridiagonal_Solve( &(a[0]), &(b[0]), &(c[0]), &(d[0]), &(v[0]), n ); - // Tridiagonal_Solve( &(a[1]), &(b[1]), &(c[1]), &(d[1]), &(v[1]), n-2 ); - - for( i = 1; i < n; ++i ){ - coef[i-1].d = (v[i] - v[i-1]) / (6*h[i-1]); - coef[i-1].c = v[i]/2; - coef[i-1].b = (f[i]-f[i-1])/h[i-1] + h[i-1]*(2*v[i] + v[i-1])/6; - coef[i-1].a = f[i]; - } - - /*fprintf( stderr, "i v coef\n" ); - for( i = 0; i < n; ++i ) - fprintf( stderr, "%d %f %f %f %f %f\n", - i, v[i], coef[i].a, coef[i].b, coef[i].c, coef[i].d ); */ + int i; + real *a, *b, *c, *d, *v; + + /* allocate space for the linear system */ + a = (real*) malloc( n * sizeof(real) ); + b = (real*) malloc( n * sizeof(real) ); + c = (real*) malloc( n * sizeof(real) ); + d = (real*) malloc( n * sizeof(real) ); + v = (real*) malloc( n * sizeof(real) ); + + /* build the linear system */ + a[0] = 0; + for ( i = 1; i < n; ++i ) + a[i] = h[i - 1]; + + b[0] = 2 * h[0]; + for ( i = 1; i < n; ++i ) + b[i] = 2 * (h[i - 1] + h[i]); + + c[n - 1] = 0; + for ( i = 0; i < n - 1; ++i ) + c[i] = h[i]; + + d[0] = 6 * (f[1] - f[0]) / h[0] - 6 * v0; + d[n - 1] = 6 * vlast - 6 * (f[n - 1] - f[n - 2] / h[n - 2]); + for ( i = 1; i < n - 1; ++i ) + d[i] = 6 * ((f[i + 1] - f[i]) / h[i] - (f[i] - f[i - 1]) / h[i - 1]); + + /*fprintf( stderr, "i a b c d\n" ); + for( i = 0; i < n; ++i ) + fprintf( stderr, "%d %f %f %f %f\n", i, a[i], b[i], c[i], d[i] );*/ + Tridiagonal_Solve( &(a[0]), &(b[0]), &(c[0]), &(d[0]), &(v[0]), n ); + // Tridiagonal_Solve( &(a[1]), &(b[1]), &(c[1]), &(d[1]), &(v[1]), n-2 ); + + for ( i = 1; i < n; ++i ) + { + coef[i - 1].d = (v[i] - v[i - 1]) / (6 * h[i - 1]); + coef[i - 1].c = v[i] / 2; + coef[i - 1].b = (f[i] - f[i - 1]) / h[i - 1] + h[i - 1] * (2 * v[i] + v[i - 1]) / 6; + coef[i - 1].a = f[i]; + } + + /*fprintf( stderr, "i v coef\n" ); + for( i = 0; i < n; ++i ) + fprintf( stderr, "%d %f %f %f %f %f\n", + i, v[i], coef[i].a, coef[i].b, coef[i].c, coef[i].d ); */ } void LR_Lookup( LR_lookup_table *t, real r, LR_data *y ) { - int i; - real base, dif; - - i = (int)(r * t->inv_dx); - if( i == 0 ) ++i; - base = (real)(i+1) * t->dx; - dif = r - base; - //fprintf( stderr, "r: %f, i: %d, base: %f, dif: %f\n", r, i, base, dif ); - - y->e_vdW = ((t->vdW[i].d*dif + t->vdW[i].c)*dif + t->vdW[i].b)*dif + - t->vdW[i].a; - y->CEvd = ((t->CEvd[i].d*dif + t->CEvd[i].c)*dif + - t->CEvd[i].b)*dif + t->CEvd[i].a; - //y->CEvd = (3*t->vdW[i].d*dif + 2*t->vdW[i].c)*dif + t->vdW[i].b; - - y->e_ele = ((t->ele[i].d*dif + t->ele[i].c)*dif + t->ele[i].b)*dif + - t->ele[i].a; - y->CEclmb = ((t->CEclmb[i].d*dif + t->CEclmb[i].c)*dif + t->CEclmb[i].b)*dif + - t->CEclmb[i].a; - - y->H = y->e_ele * EV_to_KCALpMOL / C_ele; - //y->H = ((t->H[i].d*dif + t->H[i].c)*dif + t->H[i].b)*dif + t->H[i].a; + int i; + real base, dif; + + i = (int)(r * t->inv_dx); + if ( i == 0 ) ++i; + base = (real)(i + 1) * t->dx; + dif = r - base; + //fprintf( stderr, "r: %f, i: %d, base: %f, dif: %f\n", r, i, base, dif ); + + y->e_vdW = ((t->vdW[i].d * dif + t->vdW[i].c) * dif + t->vdW[i].b) * dif + + t->vdW[i].a; + y->CEvd = ((t->CEvd[i].d * dif + t->CEvd[i].c) * dif + + t->CEvd[i].b) * dif + t->CEvd[i].a; + //y->CEvd = (3*t->vdW[i].d*dif + 2*t->vdW[i].c)*dif + t->vdW[i].b; + + y->e_ele = ((t->ele[i].d * dif + t->ele[i].c) * dif + t->ele[i].b) * dif + + t->ele[i].a; + y->CEclmb = ((t->CEclmb[i].d * dif + t->CEclmb[i].c) * dif + t->CEclmb[i].b) * dif + + t->CEclmb[i].a; + + y->H = y->e_ele * EV_to_KCALpMOL / C_ele; + //y->H = ((t->H[i].d*dif + t->H[i].c)*dif + t->H[i].b)*dif + t->H[i].a; } void Make_LR_Lookup_Table( reax_system *system, control_params *control ) { - int i, j, r; - int num_atom_types; - int existing_types[MAX_ATOM_TYPES]; - real dr; - real *h, *fh, *fvdw, *fele, *fCEvd, *fCEclmb; - real v0_vdw, v0_ele, vlast_vdw, vlast_ele; - /* real rand_dist; - real evdw_abserr, evdw_relerr, fvdw_abserr, fvdw_relerr; - real eele_abserr, eele_relerr, fele_abserr, fele_relerr; - real evdw_maxerr, eele_maxerr; - LR_data y, y_spline; */ - - /* initializations */ - vlast_ele = 0; - vlast_vdw = 0; - v0_ele = 0; - v0_vdw = 0; - - num_atom_types = system->reaxprm.num_atom_types; - dr = control->r_cut / control->tabulate; - h = (real*) malloc( (control->tabulate+1) * sizeof(real) ); - fh = (real*) malloc( (control->tabulate+1) * sizeof(real) ); - fvdw = (real*) malloc( (control->tabulate+1) * sizeof(real) ); - fCEvd = (real*) malloc( (control->tabulate+1) * sizeof(real) ); - fele = (real*) malloc( (control->tabulate+1) * sizeof(real) ); - fCEclmb = (real*) malloc( (control->tabulate+1) * sizeof(real) ); - - /* allocate Long-Range LookUp Table space based on - number of atom types in the ffield file */ - LR = (LR_lookup_table**) malloc( num_atom_types * sizeof(LR_lookup_table*) ); - for( i = 0; i < num_atom_types; ++i ) - LR[i] = (LR_lookup_table*) malloc(num_atom_types * sizeof(LR_lookup_table)); - - /* most atom types in ffield file will not exist in the current - simulation. to avoid unnecessary lookup table space, determine - the atom types that exist in the current simulation */ - for( i = 0; i < MAX_ATOM_TYPES; ++i ) - existing_types[i] = 0; - for( i = 0; i < system->N; ++i ) - existing_types[ system->atoms[i].type ] = 1; - - /* fill in the lookup table entries for existing atom types. - only lower half should be enough. */ - for( i = 0; i < num_atom_types; ++i ) - if( existing_types[i] ) - for( j = i; j < num_atom_types; ++j ) - if( existing_types[j] ) { - LR[i][j].xmin = 0; - LR[i][j].xmax = control->r_cut; - LR[i][j].n = control->tabulate + 1; - LR[i][j].dx = dr; - LR[i][j].inv_dx = control->tabulate / control->r_cut; - LR[i][j].y = (LR_data*) - malloc(LR[i][j].n * sizeof(LR_data)); - LR[i][j].H = (cubic_spline_coef*) - malloc(LR[i][j].n * sizeof(cubic_spline_coef)); - LR[i][j].vdW = (cubic_spline_coef*) - malloc(LR[i][j].n * sizeof(cubic_spline_coef)); - LR[i][j].CEvd = (cubic_spline_coef*) - malloc(LR[i][j].n * sizeof(cubic_spline_coef)); - LR[i][j].ele = (cubic_spline_coef*) - malloc(LR[i][j].n * sizeof(cubic_spline_coef)); - LR[i][j].CEclmb = (cubic_spline_coef*) - malloc(LR[i][j].n * sizeof(cubic_spline_coef)); - - for( r = 1; r <= control->tabulate; ++r ) { - LR_vdW_Coulomb( system, control, i, j, r * dr, &(LR[i][j].y[r]) ); - h[r] = LR[i][j].dx; - fh[r] = LR[i][j].y[r].H; - fvdw[r] = LR[i][j].y[r].e_vdW; - fCEvd[r] = LR[i][j].y[r].CEvd; - fele[r] = LR[i][j].y[r].e_ele; - fCEclmb[r] = LR[i][j].y[r].CEclmb; - - if( r == 1 ){ - v0_vdw = LR[i][j].y[r].CEvd; - v0_ele = LR[i][j].y[r].CEclmb; - } - else if( r == control->tabulate ){ - vlast_vdw = LR[i][j].y[r].CEvd; - vlast_ele = LR[i][j].y[r].CEclmb; - } - } - - /*fprintf( stderr, "%-6s %-6s %-6s\n", "r", "h", "fh" ); - for( r = 1; r <= control->tabulate; ++r ) - fprintf( stderr, "%f %f %f\n", r * dr, h[r], fh[r] ); */ - Natural_Cubic_Spline( &h[1], &fh[1], - &(LR[i][j].H[1]), control->tabulate+1 ); - - /*fprintf( stderr, "%-6s %-6s %-6s\n", "r", "h", "fvdw" ); - for( r = 1; r <= control->tabulate; ++r ) - fprintf( stderr, "%f %f %f\n", r * dr, h[r], fvdw[r] ); - fprintf( stderr, "v0_vdw: %f, vlast_vdw: %f\n", v0_vdw, vlast_vdw ); - */ - Complete_Cubic_Spline( &h[1], &fvdw[1], v0_vdw, vlast_vdw, - &(LR[i][j].vdW[1]), control->tabulate+1 ); - Natural_Cubic_Spline( &h[1], &fCEvd[1], - &(LR[i][j].CEvd[1]), control->tabulate+1 ); - - /*fprintf( stderr, "%-6s %-6s %-6s\n", "r", "h", "fele" ); - for( r = 1; r <= control->tabulate; ++r ) - fprintf( stderr, "%f %f %f\n", r * dr, h[r], fele[r] ); - fprintf( stderr, "v0_ele: %f, vlast_ele: %f\n", v0_ele, vlast_ele ); - */ - Complete_Cubic_Spline( &h[1], &fele[1], v0_ele, vlast_ele, - &(LR[i][j].ele[1]), control->tabulate+1 ); - Natural_Cubic_Spline( &h[1], &fCEclmb[1], - &(LR[i][j].CEclmb[1]), control->tabulate+1 ); - } - - /***** //test LR-Lookup table - evdw_maxerr = 0; - eele_maxerr = 0; - for( i = 0; i < num_atom_types; ++i ) - if( existing_types[i] ) - for( j = i; j < num_atom_types; ++j ) - if( existing_types[j] ) { - for( r = 1; r <= 100; ++r ) { - rand_dist = (real)rand()/RAND_MAX * control->r_cut; - LR_vdW_Coulomb( system, control, i, j, rand_dist, &y ); - LR_Lookup( &(LR[i][j]), rand_dist, &y_spline ); - - evdw_abserr = fabs(y.e_vdW - y_spline.e_vdW); - evdw_relerr = fabs(evdw_abserr / y.e_vdW); - fvdw_abserr = fabs(y.CEvd - y_spline.CEvd); - fvdw_relerr = fabs(fvdw_abserr / y.CEvd); - eele_abserr = fabs(y.e_ele - y_spline.e_ele); - eele_relerr = fabs(eele_abserr / y.e_ele); - fele_abserr = fabs(y.CEclmb - y_spline.CEclmb); - fele_relerr = fabs(fele_abserr / y.CEclmb); - - if( evdw_relerr > 1e-10 || eele_relerr > 1e-10 ){ - fprintf( stderr, "rand_dist = %24.15e\n", rand_dist ); - fprintf( stderr, "%24.15e %24.15e %24.15e %24.15e\n", - y.H, y_spline.H, - fabs(y.H-y_spline.H), fabs((y.H-y_spline.H)/y.H) ); - - fprintf( stderr, "%24.15e %24.15e %24.15e %24.15e\n", - y.e_vdW, y_spline.e_vdW, evdw_abserr, evdw_relerr ); - fprintf( stderr, "%24.15e %24.15e %24.15e %24.15e\n", - y.CEvd, y_spline.CEvd, fvdw_abserr, fvdw_relerr ); - - fprintf( stderr, "%24.15e %24.15e %24.15e %24.15e\n", - y.e_ele, y_spline.e_ele, eele_abserr, eele_relerr ); - fprintf( stderr, "%24.15e %24.15e %24.15e %24.15e\n", - y.CEclmb, y_spline.CEclmb, fele_abserr, fele_relerr ); - } - - if( evdw_relerr > evdw_maxerr ) - evdw_maxerr = evdw_relerr; - if( eele_relerr > eele_maxerr ) - eele_maxerr = eele_relerr; - } - } - fprintf( stderr, "evdw_maxerr: %24.15e\n", evdw_maxerr ); - fprintf( stderr, "eele_maxerr: %24.15e\n", eele_maxerr ); - *******/ - - free(h); - free(fh); - free(fvdw); - free(fCEvd); - free(fele); - free(fCEclmb); + int i, j, r; + int num_atom_types; + int existing_types[MAX_ATOM_TYPES]; + real dr; + real *h, *fh, *fvdw, *fele, *fCEvd, *fCEclmb; + real v0_vdw, v0_ele, vlast_vdw, vlast_ele; + /* real rand_dist; + real evdw_abserr, evdw_relerr, fvdw_abserr, fvdw_relerr; + real eele_abserr, eele_relerr, fele_abserr, fele_relerr; + real evdw_maxerr, eele_maxerr; + LR_data y, y_spline; */ + + /* initializations */ + vlast_ele = 0; + vlast_vdw = 0; + v0_ele = 0; + v0_vdw = 0; + + num_atom_types = system->reaxprm.num_atom_types; + dr = control->r_cut / control->tabulate; + h = (real*) malloc( (control->tabulate + 1) * sizeof(real) ); + fh = (real*) malloc( (control->tabulate + 1) * sizeof(real) ); + fvdw = (real*) malloc( (control->tabulate + 1) * sizeof(real) ); + fCEvd = (real*) malloc( (control->tabulate + 1) * sizeof(real) ); + fele = (real*) malloc( (control->tabulate + 1) * sizeof(real) ); + fCEclmb = (real*) malloc( (control->tabulate + 1) * sizeof(real) ); + + /* allocate Long-Range LookUp Table space based on + number of atom types in the ffield file */ + LR = (LR_lookup_table**) malloc( num_atom_types * sizeof(LR_lookup_table*) ); + for ( i = 0; i < num_atom_types; ++i ) + LR[i] = (LR_lookup_table*) malloc(num_atom_types * sizeof(LR_lookup_table)); + + /* most atom types in ffield file will not exist in the current + simulation. to avoid unnecessary lookup table space, determine + the atom types that exist in the current simulation */ + for ( i = 0; i < MAX_ATOM_TYPES; ++i ) + existing_types[i] = 0; + for ( i = 0; i < system->N; ++i ) + existing_types[ system->atoms[i].type ] = 1; + + /* fill in the lookup table entries for existing atom types. + only lower half should be enough. */ + for ( i = 0; i < num_atom_types; ++i ) + if ( existing_types[i] ) + for ( j = i; j < num_atom_types; ++j ) + if ( existing_types[j] ) + { + LR[i][j].xmin = 0; + LR[i][j].xmax = control->r_cut; + LR[i][j].n = control->tabulate + 1; + LR[i][j].dx = dr; + LR[i][j].inv_dx = control->tabulate / control->r_cut; + LR[i][j].y = (LR_data*) + malloc(LR[i][j].n * sizeof(LR_data)); + LR[i][j].H = (cubic_spline_coef*) + malloc(LR[i][j].n * sizeof(cubic_spline_coef)); + LR[i][j].vdW = (cubic_spline_coef*) + malloc(LR[i][j].n * sizeof(cubic_spline_coef)); + LR[i][j].CEvd = (cubic_spline_coef*) + malloc(LR[i][j].n * sizeof(cubic_spline_coef)); + LR[i][j].ele = (cubic_spline_coef*) + malloc(LR[i][j].n * sizeof(cubic_spline_coef)); + LR[i][j].CEclmb = (cubic_spline_coef*) + malloc(LR[i][j].n * sizeof(cubic_spline_coef)); + + for ( r = 1; r <= control->tabulate; ++r ) + { + LR_vdW_Coulomb( system, control, i, j, r * dr, &(LR[i][j].y[r]) ); + h[r] = LR[i][j].dx; + fh[r] = LR[i][j].y[r].H; + fvdw[r] = LR[i][j].y[r].e_vdW; + fCEvd[r] = LR[i][j].y[r].CEvd; + fele[r] = LR[i][j].y[r].e_ele; + fCEclmb[r] = LR[i][j].y[r].CEclmb; + + if ( r == 1 ) + { + v0_vdw = LR[i][j].y[r].CEvd; + v0_ele = LR[i][j].y[r].CEclmb; + } + else if ( r == control->tabulate ) + { + vlast_vdw = LR[i][j].y[r].CEvd; + vlast_ele = LR[i][j].y[r].CEclmb; + } + } + + /*fprintf( stderr, "%-6s %-6s %-6s\n", "r", "h", "fh" ); + for( r = 1; r <= control->tabulate; ++r ) + fprintf( stderr, "%f %f %f\n", r * dr, h[r], fh[r] ); */ + Natural_Cubic_Spline( &h[1], &fh[1], + &(LR[i][j].H[1]), control->tabulate + 1 ); + + /*fprintf( stderr, "%-6s %-6s %-6s\n", "r", "h", "fvdw" ); + for( r = 1; r <= control->tabulate; ++r ) + fprintf( stderr, "%f %f %f\n", r * dr, h[r], fvdw[r] ); + fprintf( stderr, "v0_vdw: %f, vlast_vdw: %f\n", v0_vdw, vlast_vdw ); + */ + Complete_Cubic_Spline( &h[1], &fvdw[1], v0_vdw, vlast_vdw, + &(LR[i][j].vdW[1]), control->tabulate + 1 ); + Natural_Cubic_Spline( &h[1], &fCEvd[1], + &(LR[i][j].CEvd[1]), control->tabulate + 1 ); + + /*fprintf( stderr, "%-6s %-6s %-6s\n", "r", "h", "fele" ); + for( r = 1; r <= control->tabulate; ++r ) + fprintf( stderr, "%f %f %f\n", r * dr, h[r], fele[r] ); + fprintf( stderr, "v0_ele: %f, vlast_ele: %f\n", v0_ele, vlast_ele ); + */ + Complete_Cubic_Spline( &h[1], &fele[1], v0_ele, vlast_ele, + &(LR[i][j].ele[1]), control->tabulate + 1 ); + Natural_Cubic_Spline( &h[1], &fCEclmb[1], + &(LR[i][j].CEclmb[1]), control->tabulate + 1 ); + } + + /***** //test LR-Lookup table + evdw_maxerr = 0; + eele_maxerr = 0; + for( i = 0; i < num_atom_types; ++i ) + if( existing_types[i] ) + for( j = i; j < num_atom_types; ++j ) + if( existing_types[j] ) { + for( r = 1; r <= 100; ++r ) { + rand_dist = (real)rand()/RAND_MAX * control->r_cut; + LR_vdW_Coulomb( system, control, i, j, rand_dist, &y ); + LR_Lookup( &(LR[i][j]), rand_dist, &y_spline ); + + evdw_abserr = fabs(y.e_vdW - y_spline.e_vdW); + evdw_relerr = fabs(evdw_abserr / y.e_vdW); + fvdw_abserr = fabs(y.CEvd - y_spline.CEvd); + fvdw_relerr = fabs(fvdw_abserr / y.CEvd); + eele_abserr = fabs(y.e_ele - y_spline.e_ele); + eele_relerr = fabs(eele_abserr / y.e_ele); + fele_abserr = fabs(y.CEclmb - y_spline.CEclmb); + fele_relerr = fabs(fele_abserr / y.CEclmb); + + if( evdw_relerr > 1e-10 || eele_relerr > 1e-10 ){ + fprintf( stderr, "rand_dist = %24.15e\n", rand_dist ); + fprintf( stderr, "%24.15e %24.15e %24.15e %24.15e\n", + y.H, y_spline.H, + fabs(y.H-y_spline.H), fabs((y.H-y_spline.H)/y.H) ); + + fprintf( stderr, "%24.15e %24.15e %24.15e %24.15e\n", + y.e_vdW, y_spline.e_vdW, evdw_abserr, evdw_relerr ); + fprintf( stderr, "%24.15e %24.15e %24.15e %24.15e\n", + y.CEvd, y_spline.CEvd, fvdw_abserr, fvdw_relerr ); + + fprintf( stderr, "%24.15e %24.15e %24.15e %24.15e\n", + y.e_ele, y_spline.e_ele, eele_abserr, eele_relerr ); + fprintf( stderr, "%24.15e %24.15e %24.15e %24.15e\n", + y.CEclmb, y_spline.CEclmb, fele_abserr, fele_relerr ); + } + + if( evdw_relerr > evdw_maxerr ) + evdw_maxerr = evdw_relerr; + if( eele_relerr > eele_maxerr ) + eele_maxerr = eele_relerr; + } + } + fprintf( stderr, "evdw_maxerr: %24.15e\n", evdw_maxerr ); + fprintf( stderr, "eele_maxerr: %24.15e\n", eele_maxerr ); + *******/ + + free(h); + free(fh); + free(fvdw); + free(fCEvd); + free(fele); + free(fCEclmb); } int Lookup_Index_Of( real x, lookup_table* t ) { - return (int)( t->a * ( x - t->xmin ) ); + return (int)( t->a * ( x - t->xmin ) ); } real Lookup( real x, lookup_table* t ) { - real x1, x2; - real b; - int i; - - /* if ( x < t->xmin) - { - fprintf(stderr,"Domain check %lf > %lf\n",t->xmin,x); - exit(0); - } - if ( x > t->xmax) - { - fprintf(stderr,"Domain check %lf < %lf\n",t->xmax,x); - exit(0); - } */ - - i = Lookup_Index_Of( x, t ); - x1 = i * t->dx + t->xmin; - x2 = (i+1) * t->dx + t->xmin; - - b = ( x2 * t->y[i] - x1 * t->y[i+1] ) * t->inv_dx; - // fprintf( stdout,"SLookup_Entry: %d, %lf, %lf, %lf, %lf: %lf, %lf\n", - // i,x1,x2,x,b,t->one_over_dx*(t->y[i+1]-t->y[i])*x+b,exp(x)); - - return t->inv_dx * ( t->y[i+1] - t->y[i] ) * x + b; + real x1, x2; + real b; + int i; + + /* if ( x < t->xmin) + { + fprintf(stderr,"Domain check %lf > %lf\n",t->xmin,x); + exit(0); + } + if ( x > t->xmax) + { + fprintf(stderr,"Domain check %lf < %lf\n",t->xmax,x); + exit(0); + } */ + + i = Lookup_Index_Of( x, t ); + x1 = i * t->dx + t->xmin; + x2 = (i + 1) * t->dx + t->xmin; + + b = ( x2 * t->y[i] - x1 * t->y[i + 1] ) * t->inv_dx; + // fprintf( stdout,"SLookup_Entry: %d, %lf, %lf, %lf, %lf: %lf, %lf\n", + // i,x1,x2,x,b,t->one_over_dx*(t->y[i+1]-t->y[i])*x+b,exp(x)); + + return t->inv_dx * ( t->y[i + 1] - t->y[i] ) * x + b; } - diff --git a/puremd_rc_1003/sPuReMD/lookup.h b/puremd_rc_1003/sPuReMD/lookup.h index 13ffc553..a0b9e516 100644 --- a/puremd_rc_1003/sPuReMD/lookup.h +++ b/puremd_rc_1003/sPuReMD/lookup.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ diff --git a/puremd_rc_1003/sPuReMD/mytypes.h b/puremd_rc_1003/sPuReMD/mytypes.h index 8d346bd4..26617a5d 100644 --- a/puremd_rc_1003/sPuReMD/mytypes.h +++ b/puremd_rc_1003/sPuReMD/mytypes.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -64,7 +64,7 @@ #define CAL_to_JOULES 4.184000 // CALories --> JOULES #define JOULES_to_CAL 1/4.184000 // JOULES --> CALories #define AMU_to_GRAM 1.6605e-24 -#define ANG_to_CM 1.0e-8 +#define ANG_to_CM 1.0e-8 #define AVOGNR 6.0221367e23 #define P_CONV 1.0e-24 * AVOGNR * JOULES_to_CAL @@ -103,8 +103,8 @@ #define GE_ATOM 6 #define X_ATOM 7 -#define ZERO 0.000000000000000e+00 -#define ALMOST_ZERO 1e-10 +#define ZERO 0.000000000000000e+00 +#define ALMOST_ZERO 1e-10 #define NEG_INF -1e10 #define NO_BOND 1e-3 #define HB_THRESHOLD 1e-2 @@ -124,10 +124,12 @@ typedef int ivec[3]; typedef real rtensor[3][3]; enum {NVE, NVT, NPT, sNPT, iNPT, ensNR, bNVT}; -enum {FAR_NBRS, NEAR_NBRS, THREE_BODIES, BONDS, OLD_BONDS, - HBONDS, DBO, DDELTA, LIST_N}; -enum {TYP_VOID, TYP_THREE_BODY, TYP_BOND, TYP_HBOND, TYP_DBO, - TYP_DDELTA, TYP_FAR_NEIGHBOR, TYP_NEAR_NEIGHBOR, TYP_N}; +enum {FAR_NBRS, NEAR_NBRS, THREE_BODIES, BONDS, OLD_BONDS, + HBONDS, DBO, DDELTA, LIST_N + }; +enum {TYP_VOID, TYP_THREE_BODY, TYP_BOND, TYP_HBOND, TYP_DBO, + TYP_DDELTA, TYP_FAR_NEIGHBOR, TYP_NEAR_NEIGHBOR, TYP_N + }; enum {UNKNOWN, WATER}; enum {NO_ANALYSIS, FRAGMENTS, REACTIONS, NUM_ANALYSIS}; enum {WRITE_ASCII, WRITE_BINARY, RF_N}; @@ -136,7 +138,7 @@ enum {XYZ, PDB, BGF, ASCII_RESTART, BINARY_RESTART, GF_N}; /* Global params mapping */ -/* +/* l[0] = p_boc1 l[1] = p_boc2 l[2] = p_coa2 @@ -179,440 +181,455 @@ l[38] = p_coa3 */ typedef struct -{ - int n_global; - real* l; - int vdw_type; +{ + int n_global; + real* l; + int vdw_type; } global_parameters; typedef struct { - /* Line one in field file */ - char name[15]; /* Two character atom name */ - - real r_s; - real valency; /* Valency of the atom */ - real mass; /* Mass of atom */ - real r_vdw; - real epsilon; - real gamma; - real r_pi; - real valency_e; - real nlp_opt; - - /* Line two in field file */ - real alpha; - real gamma_w; - real valency_boc; - real p_ovun5; - real chi; - real eta; - int p_hbond; /* Determines whether this type of atom participates in H_bonds. - It is 1 for donor H, 2 for acceptors (O,S,N), 0 for others*/ - - /* Line three in field file */ - real r_pi_pi; - real p_lp2; - real b_o_131; - real b_o_132; - real b_o_133; - - /* Line four in the field file */ - real p_ovun2; - real p_val3; - real valency_val; - real p_val5; - real rcore2; - real ecore2; - real acore2; + /* Line one in field file */ + char name[15]; /* Two character atom name */ + + real r_s; + real valency; /* Valency of the atom */ + real mass; /* Mass of atom */ + real r_vdw; + real epsilon; + real gamma; + real r_pi; + real valency_e; + real nlp_opt; + + /* Line two in field file */ + real alpha; + real gamma_w; + real valency_boc; + real p_ovun5; + real chi; + real eta; + int p_hbond; /* Determines whether this type of atom participates in H_bonds. + It is 1 for donor H, 2 for acceptors (O,S,N), 0 for others*/ + + /* Line three in field file */ + real r_pi_pi; + real p_lp2; + real b_o_131; + real b_o_132; + real b_o_133; + + /* Line four in the field file */ + real p_ovun2; + real p_val3; + real valency_val; + real p_val5; + real rcore2; + real ecore2; + real acore2; } single_body_parameters; /* Two Body Parameters */ -typedef struct { - /* Bond Order parameters */ - real p_bo1,p_bo2,p_bo3,p_bo4,p_bo5,p_bo6; - real r_s, r_p, r_pp; /* r_o distances in BO formula */ - real p_boc3, p_boc4, p_boc5; - - /* Bond Energy parameters */ - real p_be1, p_be2; - real De_s, De_p, De_pp; - - /* Over/Under coordination parameters */ - real p_ovun1; - - /* Van der Waal interaction parameters */ - real D; - real alpha; - real r_vdW; - real gamma_w; - real rcore, ecore, acore; - - /* electrostatic parameters */ - real gamma; // note: this parameter is gamma^-3 and not gamma. - - real v13cor, ovc; +typedef struct +{ + /* Bond Order parameters */ + real p_bo1, p_bo2, p_bo3, p_bo4, p_bo5, p_bo6; + real r_s, r_p, r_pp; /* r_o distances in BO formula */ + real p_boc3, p_boc4, p_boc5; + + /* Bond Energy parameters */ + real p_be1, p_be2; + real De_s, De_p, De_pp; + + /* Over/Under coordination parameters */ + real p_ovun1; + + /* Van der Waal interaction parameters */ + real D; + real alpha; + real r_vdW; + real gamma_w; + real rcore, ecore, acore; + + /* electrostatic parameters */ + real gamma; // note: this parameter is gamma^-3 and not gamma. + + real v13cor, ovc; } two_body_parameters; /* 3-body parameters */ -typedef struct { - /* valence angle */ - real theta_00; - real p_val1, p_val2, p_val4, p_val7; +typedef struct +{ + /* valence angle */ + real theta_00; + real p_val1, p_val2, p_val4, p_val7; - /* penalty */ - real p_pen1; + /* penalty */ + real p_pen1; - /* 3-body conjugation */ - real p_coa1; + /* 3-body conjugation */ + real p_coa1; } three_body_parameters; -typedef struct{ - int cnt; - three_body_parameters prm[MAX_3BODY_PARAM]; +typedef struct +{ + int cnt; + three_body_parameters prm[MAX_3BODY_PARAM]; } three_body_header; /* hydrogen-bond parameters */ -typedef struct{ - real r0_hb, p_hb1, p_hb2, p_hb3; +typedef struct +{ + real r0_hb, p_hb1, p_hb2, p_hb3; } hbond_parameters; /* 4-body parameters */ -typedef struct { - real V1, V2, V3; +typedef struct +{ + real V1, V2, V3; - /* torsion angle */ - real p_tor1; + /* torsion angle */ + real p_tor1; - /* 4-body conjugation */ - real p_cot1; + /* 4-body conjugation */ + real p_cot1; } four_body_parameters; -typedef struct{ - int cnt; - four_body_parameters prm[MAX_4BODY_PARAM]; +typedef struct +{ + int cnt; + four_body_parameters prm[MAX_4BODY_PARAM]; } four_body_header; -typedef struct{ - int num_atom_types; - global_parameters gp; - single_body_parameters *sbp; - two_body_parameters **tbp; - three_body_header ***thbp; - hbond_parameters ***hbp; - four_body_header ****fbp; +typedef struct +{ + int num_atom_types; + global_parameters gp; + single_body_parameters *sbp; + two_body_parameters **tbp; + three_body_header ***thbp; + hbond_parameters ***hbp; + four_body_header ****fbp; } reax_interaction; typedef struct { - rvec x, v, f; /* Position, velocity, force on atom */ - real q; /* Charge on the atom */ - int type; /* Type of this atom */ - char name[5]; + rvec x, v, f; /* Position, velocity, force on atom */ + real q; /* Charge on the atom */ + int type; /* Type of this atom */ + char name[5]; } reax_atom; typedef struct { - real volume; + real volume; - rvec box_norms; - rvec side_prop; - rvec nbr_box_press[27]; - // rvec lower_end; + rvec box_norms; + rvec side_prop; + rvec nbr_box_press[27]; + // rvec lower_end; - rtensor box, box_inv, old_box; - rtensor trans, trans_inv; - rtensor g; + rtensor box, box_inv, old_box; + rtensor trans, trans_inv; + rtensor g; } simulation_box; typedef struct { - int max_atoms; - int max_nbrs; - int total; - real cell_size; - ivec spread; - - ivec ncell; - rvec len; - rvec inv_len; - - int**** atoms; - int*** top; - int*** mark; - int*** start; - int*** end; - ivec**** nbrs; - rvec**** nbrs_cp; + int max_atoms; + int max_nbrs; + int total; + real cell_size; + ivec spread; + + ivec ncell; + rvec len; + rvec inv_len; + + int**** atoms; + int*** top; + int*** mark; + int*** start; + int*** end; + ivec**** nbrs; + rvec**** nbrs_cp; } grid; typedef struct { - int N; - reax_atom *atoms; - reax_interaction reaxprm; - simulation_box box; - grid g; + int N; + reax_atom *atoms; + reax_interaction reaxprm; + simulation_box box; + grid g; } reax_system; /* Simulation control parameters not related to the system */ typedef struct { - char sim_name[MAX_STR]; - char restart_from[MAX_STR]; - int restart; - int random_vel; - - int reposition_atoms; - - /* ensemble values: - 0 : NVE - 1 : NVT (Nose-Hoover) - 2 : NPT (Parrinello-Rehman-Nose-Hoover) Anisotropic - 3 : sNPT (Parrinello-Rehman-Nose-Hoover) semiisotropic - 4 : iNPT (Parrinello-Rehman-Nose-Hoover) isotropic */ - int ensemble; - int nsteps; - int periodic_boundaries; - int restrict_bonds; - int tabulate; - ivec periodic_images; - real dt; - - int reneighbor; - real vlist_cut; - real nbr_cut; - real r_cut, r_low; // upper and lower taper - real bo_cut; - real thb_cut; - real hb_cut; - real Tap7, Tap6, Tap5, Tap4, Tap3, Tap2, Tap1, Tap0; - real q_err; - int max_far_nbrs; - - real T_init, T_final, T; - real Tau_T; - int T_mode; - real T_rate, T_freq; - - real Tau_PT; - rvec P, Tau_P; - int press_mode; - real compressibility; - - int remove_CoM_vel; - - int geo_format; - - int dipole_anal; - int freq_dipole_anal; - - int diffusion_coef; - int freq_diffusion_coef; - int restrict_type; - - int refactor; - real droptol; - - int molec_anal; - int freq_molec_anal; - real bg_cut; - int num_ignored; - int ignore[MAX_ATOM_TYPES]; + char sim_name[MAX_STR]; + char restart_from[MAX_STR]; + int restart; + int random_vel; + + int reposition_atoms; + + /* ensemble values: + 0 : NVE + 1 : NVT (Nose-Hoover) + 2 : NPT (Parrinello-Rehman-Nose-Hoover) Anisotropic + 3 : sNPT (Parrinello-Rehman-Nose-Hoover) semiisotropic + 4 : iNPT (Parrinello-Rehman-Nose-Hoover) isotropic */ + int ensemble; + int nsteps; + int periodic_boundaries; + int restrict_bonds; + int tabulate; + ivec periodic_images; + real dt; + + int reneighbor; + real vlist_cut; + real nbr_cut; + real r_cut, r_low; // upper and lower taper + real bo_cut; + real thb_cut; + real hb_cut; + real Tap7, Tap6, Tap5, Tap4, Tap3, Tap2, Tap1, Tap0; + real q_err; + int max_far_nbrs; + + real T_init, T_final, T; + real Tau_T; + int T_mode; + real T_rate, T_freq; + + real Tau_PT; + rvec P, Tau_P; + int press_mode; + real compressibility; + + int remove_CoM_vel; + + int geo_format; + + int dipole_anal; + int freq_dipole_anal; + + int diffusion_coef; + int freq_diffusion_coef; + int restrict_type; + + int refactor; + real droptol; + + int molec_anal; + int freq_molec_anal; + real bg_cut; + int num_ignored; + int ignore[MAX_ATOM_TYPES]; } control_params; typedef struct { - real T; - real xi; - real v_xi; - real v_xi_old; - real G_xi; + real T; + real xi; + real v_xi; + real v_xi_old; + real G_xi; } thermostat; typedef struct { - real P; - real eps; - real v_eps; - real v_eps_old; - real a_eps; + real P; + real eps; + real v_eps; + real v_eps_old; + real a_eps; } isotropic_barostat; typedef struct { - rtensor P; - real P_scalar; - - real eps; - real v_eps; - real v_eps_old; - real a_eps; + rtensor P; + real P_scalar; - rtensor h0; - rtensor v_g0; - rtensor v_g0_old; - rtensor a_g0; + real eps; + real v_eps; + real v_eps_old; + real a_eps; + + rtensor h0; + rtensor v_g0; + rtensor v_g0_old; + rtensor a_g0; } flexible_barostat; typedef struct { - real start; - real end; - real elapsed; - - real total; - real nbrs; - real init_forces; - real bonded; - real nonb; - real QEq; - int matvecs; + real start; + real end; + real elapsed; + + real total; + real nbrs; + real init_forces; + real bonded; + real nonb; + real QEq; + int matvecs; } reax_timing; typedef struct { - int step; - int prev_steps; - real time; - - real M; /* Total Mass */ - real inv_M; /* 1 / Total Mass */ - - rvec xcm; /* Center of mass */ - rvec vcm; /* Center of mass velocity */ - rvec fcm; /* Center of mass force */ - rvec amcm; /* Angular momentum of CoM */ - rvec avcm; /* Angular velocity of CoM */ - real etran_cm; /* Translational kinetic energy of CoM */ - real erot_cm; /* Rotational kinetic energy of CoM */ - - rtensor kinetic; /* Kinetic energy tensor */ - rtensor virial; /* Hydrodynamic virial */ - - real E_Tot; - real E_Kin; /* Total kinetic energy */ - real E_Pot; - - real E_BE; /* Total bond energy */ - real E_Ov; /* Total over coordination */ - real E_Un; /* Total under coordination energy */ - real E_Lp; /* Total under coordination energy */ - real E_Ang; /* Total valance angle energy */ - real E_Pen; /* Total penalty energy */ - real E_Coa; /* Total three body conjgation energy */ - real E_HB; /* Total Hydrogen bond energy */ - real E_Tor; /* Total torsional energy */ - real E_Con; /* Total four body conjugation energy */ - real E_vdW; /* Total van der Waals energy */ - real E_Ele; /* Total electrostatics energy */ - real E_Pol; /* Polarization energy */ - - real N_f; /*Number of degrees of freedom */ - rvec t_scale; - rtensor p_scale; - thermostat therm; /* Used in Nose_Hoover method */ - isotropic_barostat iso_bar; - flexible_barostat flex_bar; - real inv_W; - - rvec int_press; - rvec ext_press; - real kin_press; - rvec tot_press; - - reax_timing timing; + int step; + int prev_steps; + real time; + + real M; /* Total Mass */ + real inv_M; /* 1 / Total Mass */ + + rvec xcm; /* Center of mass */ + rvec vcm; /* Center of mass velocity */ + rvec fcm; /* Center of mass force */ + rvec amcm; /* Angular momentum of CoM */ + rvec avcm; /* Angular velocity of CoM */ + real etran_cm; /* Translational kinetic energy of CoM */ + real erot_cm; /* Rotational kinetic energy of CoM */ + + rtensor kinetic; /* Kinetic energy tensor */ + rtensor virial; /* Hydrodynamic virial */ + + real E_Tot; + real E_Kin; /* Total kinetic energy */ + real E_Pot; + + real E_BE; /* Total bond energy */ + real E_Ov; /* Total over coordination */ + real E_Un; /* Total under coordination energy */ + real E_Lp; /* Total under coordination energy */ + real E_Ang; /* Total valance angle energy */ + real E_Pen; /* Total penalty energy */ + real E_Coa; /* Total three body conjgation energy */ + real E_HB; /* Total Hydrogen bond energy */ + real E_Tor; /* Total torsional energy */ + real E_Con; /* Total four body conjugation energy */ + real E_vdW; /* Total van der Waals energy */ + real E_Ele; /* Total electrostatics energy */ + real E_Pol; /* Polarization energy */ + + real N_f; /*Number of degrees of freedom */ + rvec t_scale; + rtensor p_scale; + thermostat therm; /* Used in Nose_Hoover method */ + isotropic_barostat iso_bar; + flexible_barostat flex_bar; + real inv_W; + + rvec int_press; + rvec ext_press; + real kin_press; + rvec tot_press; + + reax_timing timing; } simulation_data; -typedef struct { - int thb; - int pthb; /* pointer to the third body on the central atom's nbrlist */ - real theta, cos_theta; - rvec dcos_di, dcos_dj, dcos_dk; +typedef struct +{ + int thb; + int pthb; /* pointer to the third body on the central atom's nbrlist */ + real theta, cos_theta; + rvec dcos_di, dcos_dj, dcos_dk; } three_body_interaction_data; -typedef struct { - int nbr; - ivec rel_box; - // rvec ext_factor; - real d; - rvec dvec; +typedef struct +{ + int nbr; + ivec rel_box; + // rvec ext_factor; + real d; + rvec dvec; } near_neighbor_data; -typedef struct { - int nbr; - ivec rel_box; - // rvec ext_factor; - real d; - rvec dvec; - // real H; //, Tap, inv_dr3gamij_1, inv_dr3gamij_3; +typedef struct +{ + int nbr; + ivec rel_box; + // rvec ext_factor; + real d; + rvec dvec; + // real H; //, Tap, inv_dr3gamij_1, inv_dr3gamij_3; } far_neighbor_data; -typedef struct { - int nbr; - int scl; - far_neighbor_data *ptr; +typedef struct +{ + int nbr; + int scl; + far_neighbor_data *ptr; } hbond_data; -typedef struct { - int wrt; - rvec dVal; +typedef struct +{ + int wrt; + rvec dVal; } dDelta_data; -typedef struct { - int wrt; - rvec dBO, dBOpi, dBOpi2; +typedef struct +{ + int wrt; + rvec dBO, dBOpi, dBOpi2; } dbond_data; -typedef struct { - real BO, BO_s, BO_pi, BO_pi2; - real Cdbo, Cdbopi, Cdbopi2; - real C1dbo, C2dbo, C3dbo; - real C1dbopi, C2dbopi, C3dbopi, C4dbopi; - real C1dbopi2, C2dbopi2, C3dbopi2, C4dbopi2; - rvec dBOp, dln_BOp_s, dln_BOp_pi, dln_BOp_pi2; +typedef struct +{ + real BO, BO_s, BO_pi, BO_pi2; + real Cdbo, Cdbopi, Cdbopi2; + real C1dbo, C2dbo, C3dbo; + real C1dbopi, C2dbopi, C3dbopi, C4dbopi; + real C1dbopi2, C2dbopi2, C3dbopi2, C4dbopi2; + rvec dBOp, dln_BOp_s, dln_BOp_pi, dln_BOp_pi2; } bond_order_data; -typedef struct { - int nbr; - int sym_index; - int dbond_index; - ivec rel_box; - // rvec ext_factor; - real d; - rvec dvec; - bond_order_data bo_data; +typedef struct +{ + int nbr; + int sym_index; + int dbond_index; + ivec rel_box; + // rvec ext_factor; + real d; + rvec dvec; + bond_order_data bo_data; } bond_data; @@ -625,9 +642,10 @@ typedef struct { // to avoid having the compiler add padding bytes (manual alignment along word boundary) // Warning: padding is implementation (compiler) dependent, so not portable, // and also potentially dangerous -typedef struct { - int j; - real val; +typedef struct +{ + int j; + real val; } sparse_matrix_entry; /* compressed row storage (crs) format @@ -639,231 +657,234 @@ typedef struct { * start: row pointer (last element contains NNZ + 1) * entries: (column index, val) pairs * */ -typedef struct { - int n, m; - int *start; - sparse_matrix_entry *entries; +typedef struct +{ + int n, m; + int *start; + sparse_matrix_entry *entries; // int *j; // real *val; } sparse_matrix; -typedef struct { - int num_far; - int Htop; - int hbonds; - int num_hbonds; - int bonds; - int num_bonds; - int num_3body; - int gcell_atoms; +typedef struct +{ + int num_far; + int Htop; + int hbonds; + int num_hbonds; + int bonds; + int num_bonds; + int num_3body; + int gcell_atoms; } reallocate_data; -typedef struct { - /* bond order related storage */ - real *total_bond_order; - real *Deltap, *Deltap_boc; - real *Delta, *Delta_lp, *Delta_lp_temp, *Delta_e, *Delta_boc; - real *dDelta_lp, *dDelta_lp_temp; - real *nlp, *nlp_temp, *Clp, *vlpex; - rvec *dDeltap_self; - - /* QEq storage */ - sparse_matrix *H, *L, *U; - real *droptol; - real *w; - real *Hdia_inv; - real *b, *b_s, *b_t, *b_prc, *b_prm; - real **s, **t; - real *s_t; //, *s_old, *t_old, *s_oldest, *t_oldest; - - /* GMRES related storage */ - real *y, *z, *g; - real *hc, *hs; - real **h, **rn, **v; - /* CG related storage */ - real *r, *d, *q, *p; - int s_dims, t_dims; - - int num_H; - int *hbond_index; // for hydrogen bonds - - rvec *v_const, *f_old, *a; // used in integrators - - real *CdDelta; // coefficient of dDelta for force calculations - - int *mark, *old_mark; // storage for analysis - rvec *x_old; - - /* storage space for bond restrictions */ - int *map_serials; - int *orig_id; - int *restricted; - int **restricted_list; - - reallocate_data realloc; - +typedef struct +{ + /* bond order related storage */ + real *total_bond_order; + real *Deltap, *Deltap_boc; + real *Delta, *Delta_lp, *Delta_lp_temp, *Delta_e, *Delta_boc; + real *dDelta_lp, *dDelta_lp_temp; + real *nlp, *nlp_temp, *Clp, *vlpex; + rvec *dDeltap_self; + + /* QEq storage */ + sparse_matrix *H, *L, *U; + real *droptol; + real *w; + real *Hdia_inv; + real *b, *b_s, *b_t, *b_prc, *b_prm; + real **s, **t; + real *s_t; //, *s_old, *t_old, *s_oldest, *t_oldest; + + /* GMRES related storage */ + real *y, *z, *g; + real *hc, *hs; + real **h, **rn, **v; + /* CG related storage */ + real *r, *d, *q, *p; + int s_dims, t_dims; + + int num_H; + int *hbond_index; // for hydrogen bonds + + rvec *v_const, *f_old, *a; // used in integrators + + real *CdDelta; // coefficient of dDelta for force calculations + + int *mark, *old_mark; // storage for analysis + rvec *x_old; + + /* storage space for bond restrictions */ + int *map_serials; + int *orig_id; + int *restricted; + int **restricted_list; + + reallocate_data realloc; + #ifdef TEST_FORCES - rvec *f_ele; - rvec *f_vdw; - rvec *f_bo; - rvec *f_be; - rvec *f_lp; - rvec *f_ov; - rvec *f_un; - rvec *f_ang; - rvec *f_coa; - rvec *f_pen; - rvec *f_hb; - rvec *f_tor; - rvec *f_con; - rvec *dDelta; /* Calculated on the fly in bond_orders.c */ + rvec *f_ele; + rvec *f_vdw; + rvec *f_bo; + rvec *f_be; + rvec *f_lp; + rvec *f_ov; + rvec *f_un; + rvec *f_ang; + rvec *f_coa; + rvec *f_pen; + rvec *f_hb; + rvec *f_tor; + rvec *f_con; + rvec *dDelta; /* Calculated on the fly in bond_orders.c */ #endif } static_storage; typedef struct { - int n; - int num_intrs; - int *index; - int *end_index; - int type; - union - { - void *v; - three_body_interaction_data *three_body_list; - bond_data *bond_list; - dbond_data *dbo_list; - dDelta_data *dDelta_list; - far_neighbor_data *far_nbr_list; - near_neighbor_data *near_nbr_list; - hbond_data *hbond_list; - }select; + int n; + int num_intrs; + int *index; + int *end_index; + int type; + union + { + void *v; + three_body_interaction_data *three_body_list; + bond_data *bond_list; + dbond_data *dbo_list; + dDelta_data *dDelta_list; + far_neighbor_data *far_nbr_list; + near_neighbor_data *near_nbr_list; + hbond_data *hbond_list; + } select; } list; typedef struct { - FILE *trj; - FILE *out; - FILE *pot; - FILE *log; - FILE *mol, *ign; - FILE *dpl; - FILE *drft; - FILE *pdb; - FILE *prs; - - int write_steps; - int traj_compress; - int traj_format; - char traj_title[81]; - int atom_format; - int bond_info; - int angle_info; - - int restart_format; - int restart_freq; - int debug_level; - int energy_update_freq; - - // trajectory output functions - int (* write_header)( reax_system*, control_params*, static_storage*, void* ); - int (* append_traj_frame)(reax_system*, control_params*, - simulation_data*, static_storage*, list **, void* ); - int (* write)( FILE *, const char *, ... ); + FILE *trj; + FILE *out; + FILE *pot; + FILE *log; + FILE *mol, *ign; + FILE *dpl; + FILE *drft; + FILE *pdb; + FILE *prs; + + int write_steps; + int traj_compress; + int traj_format; + char traj_title[81]; + int atom_format; + int bond_info; + int angle_info; + + int restart_format; + int restart_freq; + int debug_level; + int energy_update_freq; + + // trajectory output functions + int (* write_header)( reax_system*, control_params*, static_storage*, void* ); + int (* append_traj_frame)(reax_system*, control_params*, + simulation_data*, static_storage*, list **, void* ); + int (* write)( FILE *, const char *, ... ); #ifdef TEST_ENERGY - FILE *ebond; - FILE *elp, *eov, *eun; - FILE *eval, *epen, *ecoa; - FILE *ehb; - FILE *etor, *econ; - FILE *evdw, *ecou; + FILE *ebond; + FILE *elp, *eov, *eun; + FILE *eval, *epen, *ecoa; + FILE *ehb; + FILE *etor, *econ; + FILE *evdw, *ecou; #endif - FILE *ftot; + FILE *ftot; #ifdef TEST_FORCES - FILE *fbo, *fdbo; - FILE *fbond; - FILE *flp, *fatom; - FILE *f3body; - FILE *fhb; - FILE *f4body; - FILE *fnonb; - FILE *ftot2; + FILE *fbo, *fdbo; + FILE *fbond; + FILE *flp, *fatom; + FILE *f3body; + FILE *fhb; + FILE *f4body; + FILE *fnonb; + FILE *ftot2; #endif } output_controls; typedef struct { - int atom_count; - int atom_list[MAX_MOLECULE_SIZE]; - int mtypes[MAX_ATOM_TYPES]; -} molecule; + int atom_count; + int atom_list[MAX_MOLECULE_SIZE]; + int mtypes[MAX_ATOM_TYPES]; +} molecule; typedef struct { - real H; - real e_vdW, CEvd; - real e_ele, CEclmb; + real H; + real e_vdW, CEvd; + real e_ele, CEclmb; } LR_data; typedef struct { - real a, b, c, d; + real a, b, c, d; } cubic_spline_coef; typedef struct { - real xmin, xmax; - int n; - real dx, inv_dx; - real a; + real xmin, xmax; + int n; + real dx, inv_dx; + real a; - real m; - real c; + real m; + real c; - real *y; + real *y; } lookup_table; typedef struct { - real xmin, xmax; - int n; - real dx, inv_dx; - real a; - real m; - real c; - - LR_data *y; - cubic_spline_coef *H; - cubic_spline_coef *vdW, *CEvd; - cubic_spline_coef *ele, *CEclmb; + real xmin, xmax; + int n; + real dx, inv_dx; + real a; + real m; + real c; + + LR_data *y; + cubic_spline_coef *H; + cubic_spline_coef *vdW, *CEvd; + cubic_spline_coef *ele, *CEclmb; } LR_lookup_table; -typedef void (*interaction_function)(reax_system*, control_params*, - simulation_data*, static_storage*, - list**, output_controls*); +typedef void (*interaction_function)(reax_system*, control_params*, + simulation_data*, static_storage*, + list**, output_controls*); interaction_function Interaction_Functions[NO_OF_INTERACTIONS]; -typedef void (*evolve_function)(reax_system*, control_params*, - simulation_data*, static_storage*, - list**, output_controls*); +typedef void (*evolve_function)(reax_system*, control_params*, + simulation_data*, static_storage*, + list**, output_controls*); typedef real (*lookup_function)(real); lookup_table Exp, Sqrt, Cube_Root, Four_Third_Root, Cos, Sin, ACos; LR_lookup_table **LR; -typedef void (*get_far_neighbors_function)(rvec, rvec, simulation_box*, - control_params*, far_neighbor_data*, - int*); +typedef void (*get_far_neighbors_function)(rvec, rvec, simulation_box*, + control_params*, far_neighbor_data*, + int*); #endif diff --git a/puremd_rc_1003/sPuReMD/neighbors.c b/puremd_rc_1003/sPuReMD/neighbors.c index 9d3821e7..9b04cfa8 100644 --- a/puremd_rc_1003/sPuReMD/neighbors.c +++ b/puremd_rc_1003/sPuReMD/neighbors.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -31,115 +31,125 @@ inline real DistSqr_to_CP( rvec cp, rvec x ) { - int i; - real d_sqr = 0; + int i; + real d_sqr = 0; - for( i = 0; i < 3; ++i ) - if( cp[i] > NEG_INF ) - d_sqr += SQR( cp[i] - x[i] ); + for ( i = 0; i < 3; ++i ) + if ( cp[i] > NEG_INF ) + d_sqr += SQR( cp[i] - x[i] ); - return d_sqr; + return d_sqr; } -void Generate_Neighbor_Lists( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Generate_Neighbor_Lists( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i, j, k, l, m, itr; - int x, y, z; - int atom1, atom2, max; - int num_far; - int *nbr_atoms; - ivec *nbrs; - rvec *nbrs_cp; - grid *g; - list *far_nbrs; - far_neighbor_data *nbr_data; - real t_start, t_elapsed; - - t_start = Get_Time( ); - // fprintf( stderr, "\n\tentered nbrs - " ); - g = &( system->g ); - far_nbrs = (*lists) + FAR_NBRS; - Bin_Atoms( system, workspace ); - // fprintf( stderr, "atoms sorted - " ); - num_far = 0; - - /* first pick up a cell in the grid */ - for( i = 0; i < g->ncell[0]; i++ ) - for( j = 0; j < g->ncell[1]; j++ ) - for( k = 0; k < g->ncell[2]; k++ ) { - nbrs = g->nbrs[i][j][k]; - nbrs_cp = g->nbrs_cp[i][j][k]; - //fprintf( stderr, "gridcell %d %d %d\n", i, j, k ); - - /* pick up an atom from the current cell */ - for(l = 0; l < g->top[i][j][k]; ++l ){ - atom1 = g->atoms[i][j][k][l]; - Set_Start_Index( atom1, num_far, far_nbrs ); - //fprintf( stderr, "\tatom %d\n", atom1 ); - - itr = 0; - while( nbrs[itr][0] >= 0 ){ - x = nbrs[itr][0]; - y = nbrs[itr][1]; - z = nbrs[itr][2]; - //fprintf( stderr, "\t\tgridcell %d %d %d\n", x, y, z ); - - if( DistSqr_to_CP(nbrs_cp[itr], system->atoms[atom1].x ) <= - SQR(control->vlist_cut) ) { - nbr_atoms = g->atoms[x][y][z]; - max = g->top[x][y][z]; - //fprintf( stderr, "\t\tmax: %d\n", max ); - - /* pick up another atom from the neighbor cell */ - for( m = 0; m < max; ++m ) { - atom2 = nbr_atoms[m]; - if( atom1 > atom2 ) { - nbr_data = &(far_nbrs->select.far_nbr_list[num_far]); - //fprintf (stderr, " %f %f %f \n", nbr_data->dvec[0], nbr_data->dvec[1], nbr_data->dvec[2]); - if(Are_Far_Neighbors(system->atoms[atom1].x, - system->atoms[atom2].x, - &(system->box), control->vlist_cut, - nbr_data)) { - nbr_data->nbr = atom2; - ++num_far; - } - } - } - } - - ++itr; - } - - Set_End_Index( atom1, num_far, far_nbrs ); - //fprintf(stderr, "i:%d, start: %d, end: %d - itr: %d\n", - // atom1,Start_Index(atom1,far_nbrs),End_Index(atom1,far_nbrs), - // itr); - } - } - - if( num_far > far_nbrs->num_intrs * DANGER_ZONE ) { - workspace->realloc.num_far = num_far; - if( num_far > far_nbrs->num_intrs ){ - fprintf( stderr, "step%d-ran out of space on far_nbrs: top=%d, max=%d", - data->step, num_far, far_nbrs->num_intrs ); - exit( INSUFFICIENT_SPACE ); + int i, j, k, l, m, itr; + int x, y, z; + int atom1, atom2, max; + int num_far; + int *nbr_atoms; + ivec *nbrs; + rvec *nbrs_cp; + grid *g; + list *far_nbrs; + far_neighbor_data *nbr_data; + real t_start, t_elapsed; + + t_start = Get_Time( ); + // fprintf( stderr, "\n\tentered nbrs - " ); + g = &( system->g ); + far_nbrs = (*lists) + FAR_NBRS; + Bin_Atoms( system, workspace ); + // fprintf( stderr, "atoms sorted - " ); + num_far = 0; + + /* first pick up a cell in the grid */ + for ( i = 0; i < g->ncell[0]; i++ ) + for ( j = 0; j < g->ncell[1]; j++ ) + for ( k = 0; k < g->ncell[2]; k++ ) + { + nbrs = g->nbrs[i][j][k]; + nbrs_cp = g->nbrs_cp[i][j][k]; + //fprintf( stderr, "gridcell %d %d %d\n", i, j, k ); + + /* pick up an atom from the current cell */ + for (l = 0; l < g->top[i][j][k]; ++l ) + { + atom1 = g->atoms[i][j][k][l]; + Set_Start_Index( atom1, num_far, far_nbrs ); + //fprintf( stderr, "\tatom %d\n", atom1 ); + + itr = 0; + while ( nbrs[itr][0] >= 0 ) + { + x = nbrs[itr][0]; + y = nbrs[itr][1]; + z = nbrs[itr][2]; + //fprintf( stderr, "\t\tgridcell %d %d %d\n", x, y, z ); + + if ( DistSqr_to_CP(nbrs_cp[itr], system->atoms[atom1].x ) <= + SQR(control->vlist_cut) ) + { + nbr_atoms = g->atoms[x][y][z]; + max = g->top[x][y][z]; + //fprintf( stderr, "\t\tmax: %d\n", max ); + + /* pick up another atom from the neighbor cell */ + for ( m = 0; m < max; ++m ) + { + atom2 = nbr_atoms[m]; + if ( atom1 > atom2 ) + { + nbr_data = &(far_nbrs->select.far_nbr_list[num_far]); + //fprintf (stderr, " %f %f %f \n", nbr_data->dvec[0], nbr_data->dvec[1], nbr_data->dvec[2]); + if (Are_Far_Neighbors(system->atoms[atom1].x, + system->atoms[atom2].x, + &(system->box), control->vlist_cut, + nbr_data)) + { + nbr_data->nbr = atom2; + ++num_far; + } + } + } + } + + ++itr; + } + + Set_End_Index( atom1, num_far, far_nbrs ); + //fprintf(stderr, "i:%d, start: %d, end: %d - itr: %d\n", + // atom1,Start_Index(atom1,far_nbrs),End_Index(atom1,far_nbrs), + // itr); + } + } + + if ( num_far > far_nbrs->num_intrs * DANGER_ZONE ) + { + workspace->realloc.num_far = num_far; + if ( num_far > far_nbrs->num_intrs ) + { + fprintf( stderr, "step%d-ran out of space on far_nbrs: top=%d, max=%d", + data->step, num_far, far_nbrs->num_intrs ); + exit( INSUFFICIENT_SPACE ); + } } - } - t_elapsed = Get_Timing_Info( t_start ); - data->timing.nbrs += t_elapsed; + t_elapsed = Get_Timing_Info( t_start ); + data->timing.nbrs += t_elapsed; #if defined(DEBUG) - for( i = 0; i < system->N; ++i ) { - qsort( &(far_nbrs->select.far_nbr_list[ Start_Index(i, far_nbrs) ]), - Num_Entries(i, far_nbrs), sizeof(far_neighbor_data), - compare_far_nbrs ); - } + for ( i = 0; i < system->N; ++i ) + { + qsort( &(far_nbrs->select.far_nbr_list[ Start_Index(i, far_nbrs) ]), + Num_Entries(i, far_nbrs), sizeof(far_neighbor_data), + compare_far_nbrs ); + } #endif -#if defined(DEBUG_FOCUS) +#if defined(DEBUG_FOCUS) fprintf( stderr, "nbrs - "); fprintf( stderr, "nbrs done, num_far: %d\n", num_far ); #endif @@ -149,128 +159,134 @@ void Generate_Neighbor_Lists( reax_system *system, control_params *control, } -int Estimate_NumNeighbors( reax_system *system, control_params *control, - static_storage *workspace, list **lists ) +int Estimate_NumNeighbors( reax_system *system, control_params *control, + static_storage *workspace, list **lists ) { - int i, j, k, l, m, itr; - int x, y, z; - int atom1, atom2, max; - int num_far; - int *nbr_atoms; - ivec *nbrs; - rvec *nbrs_cp; - grid *g; - far_neighbor_data nbr_data; - - // fprintf( stderr, "\n\tentered nbrs - " ); - g = &( system->g ); - Bin_Atoms( system, workspace ); - // fprintf( stderr, "atoms sorted - " ); - num_far = 0; - - /* first pick up a cell in the grid */ - for( i = 0; i < g->ncell[0]; i++ ) - for( j = 0; j < g->ncell[1]; j++ ) - for( k = 0; k < g->ncell[2]; k++ ) { - nbrs = g->nbrs[i][j][k]; - nbrs_cp = g->nbrs_cp[i][j][k]; - //fprintf( stderr, "gridcell %d %d %d\n", i, j, k ); - - /* pick up an atom from the current cell */ - for(l = 0; l < g->top[i][j][k]; ++l ){ - atom1 = g->atoms[i][j][k][l]; - - itr = 0; - while( nbrs[itr][0] >= 0 ){ - x = nbrs[itr][0]; - y = nbrs[itr][1]; - z = nbrs[itr][2]; - //fprintf( stderr, "\t\tgridcell %d %d %d\n", x, y, z ); - - if( DistSqr_to_CP(nbrs_cp[itr], system->atoms[atom1].x ) <= - SQR(control->vlist_cut) ) { - nbr_atoms = g->atoms[x][y][z]; - max = g->top[x][y][z]; - //fprintf( stderr, "\t\tmax: %d\n", max ); - - /* pick up another atom from the neighbor cell - - we have to compare atom1 with its own periodic images as well, - that's why there is also equality in the if stmt below */ - for( m = 0; m < max; ++m ) { - atom2 = nbr_atoms[m]; - //if( nbrs[itr+1][0] >= 0 || atom1 > atom2 ) { - if( atom1 > atom2 ) { - if(Are_Far_Neighbors(system->atoms[atom1].x, - system->atoms[atom2].x, - &(system->box), control->vlist_cut, - &nbr_data)) - ++num_far; - } - } - } - - ++itr; - } - } - } - -#if defined(DEBUG_FOCUS) - fprintf( stderr, "estimate nbrs done, num_far: %d\n", num_far ); + int i, j, k, l, m, itr; + int x, y, z; + int atom1, atom2, max; + int num_far; + int *nbr_atoms; + ivec *nbrs; + rvec *nbrs_cp; + grid *g; + far_neighbor_data nbr_data; + + // fprintf( stderr, "\n\tentered nbrs - " ); + g = &( system->g ); + Bin_Atoms( system, workspace ); + // fprintf( stderr, "atoms sorted - " ); + num_far = 0; + + /* first pick up a cell in the grid */ + for ( i = 0; i < g->ncell[0]; i++ ) + for ( j = 0; j < g->ncell[1]; j++ ) + for ( k = 0; k < g->ncell[2]; k++ ) + { + nbrs = g->nbrs[i][j][k]; + nbrs_cp = g->nbrs_cp[i][j][k]; + //fprintf( stderr, "gridcell %d %d %d\n", i, j, k ); + + /* pick up an atom from the current cell */ + for (l = 0; l < g->top[i][j][k]; ++l ) + { + atom1 = g->atoms[i][j][k][l]; + + itr = 0; + while ( nbrs[itr][0] >= 0 ) + { + x = nbrs[itr][0]; + y = nbrs[itr][1]; + z = nbrs[itr][2]; + //fprintf( stderr, "\t\tgridcell %d %d %d\n", x, y, z ); + + if ( DistSqr_to_CP(nbrs_cp[itr], system->atoms[atom1].x ) <= + SQR(control->vlist_cut) ) + { + nbr_atoms = g->atoms[x][y][z]; + max = g->top[x][y][z]; + //fprintf( stderr, "\t\tmax: %d\n", max ); + + /* pick up another atom from the neighbor cell - + we have to compare atom1 with its own periodic images as well, + that's why there is also equality in the if stmt below */ + for ( m = 0; m < max; ++m ) + { + atom2 = nbr_atoms[m]; + //if( nbrs[itr+1][0] >= 0 || atom1 > atom2 ) { + if ( atom1 > atom2 ) + { + if (Are_Far_Neighbors(system->atoms[atom1].x, + system->atoms[atom2].x, + &(system->box), control->vlist_cut, + &nbr_data)) + ++num_far; + } + } + } + + ++itr; + } + } + } + +#if defined(DEBUG_FOCUS) + fprintf( stderr, "estimate nbrs done, num_far: %d\n", num_far ); #endif - return num_far * SAFE_ZONE; + return num_far * SAFE_ZONE; } #if defined DONE -void Choose_Neighbor_Finder( reax_system *system, control_params *control, - get_far_neighbors_function *Get_Far_Neighbors ) +void Choose_Neighbor_Finder( reax_system *system, control_params *control, + get_far_neighbors_function *Get_Far_Neighbors ) { - if( control->periodic_boundaries ) + if ( control->periodic_boundaries ) { - if( system->box.box_norms[0] > 2.0 * control->vlist_cut && - system->box.box_norms[1] > 2.0 * control->vlist_cut && - system->box.box_norms[2] > 2.0 * control->vlist_cut ) - (*Get_Far_Neighbors) = Get_Periodic_Far_Neighbors_Big_Box; - else (*Get_Far_Neighbors) = Get_Periodic_Far_Neighbors_Small_Box; + if ( system->box.box_norms[0] > 2.0 * control->vlist_cut && + system->box.box_norms[1] > 2.0 * control->vlist_cut && + system->box.box_norms[2] > 2.0 * control->vlist_cut ) + (*Get_Far_Neighbors) = Get_Periodic_Far_Neighbors_Big_Box; + else (*Get_Far_Neighbors) = Get_Periodic_Far_Neighbors_Small_Box; } - else - (*Get_Far_Neighbors) = Get_NonPeriodic_Far_Neighbors; + else + (*Get_Far_Neighbors) = Get_NonPeriodic_Far_Neighbors; } int compare_near_nbrs(const void *v1, const void *v2) { - return ((*(near_neighbor_data *)v1).nbr - (*(near_neighbor_data *)v2).nbr); + return ((*(near_neighbor_data *)v1).nbr - (*(near_neighbor_data *)v2).nbr); } int compare_far_nbrs(const void *v1, const void *v2) { - return ((*(far_neighbor_data *)v1).nbr - (*(far_neighbor_data *)v2).nbr); + return ((*(far_neighbor_data *)v1).nbr - (*(far_neighbor_data *)v2).nbr); } inline void Set_Far_Neighbor( far_neighbor_data *dest, int nbr, real d, real C, - rvec dvec, ivec rel_box/*, rvec ext_factor*/ ) + rvec dvec, ivec rel_box/*, rvec ext_factor*/ ) { - dest->nbr = nbr; - dest->d = d; - rvec_Scale( dest->dvec, C, dvec ); - ivec_Copy( dest->rel_box, rel_box ); - // rvec_Scale( dest->ext_factor, C, ext_factor ); + dest->nbr = nbr; + dest->d = d; + rvec_Scale( dest->dvec, C, dvec ); + ivec_Copy( dest->rel_box, rel_box ); + // rvec_Scale( dest->ext_factor, C, ext_factor ); } inline void Set_Near_Neighbor(near_neighbor_data *dest, int nbr, real d, real C, - rvec dvec, ivec rel_box/*, rvec ext_factor*/) + rvec dvec, ivec rel_box/*, rvec ext_factor*/) { - dest->nbr = nbr; - dest->d = d; - rvec_Scale( dest->dvec, C, dvec ); - ivec_Scale( dest->rel_box, C, rel_box ); - // rvec_Scale( dest->ext_factor, C, ext_factor ); + dest->nbr = nbr; + dest->d = d; + rvec_Scale( dest->dvec, C, dvec ); + ivec_Scale( dest->rel_box, C, rel_box ); + // rvec_Scale( dest->ext_factor, C, ext_factor ); } @@ -278,381 +294,399 @@ inline void Set_Near_Neighbor(near_neighbor_data *dest, int nbr, real d, real C, atom1 and atom2 are allowed to bond with each other */ inline int can_Bond( static_storage *workspace, int atom1, int atom2 ) { - int i; + int i; - // fprintf( stderr, "can bond %6d %6d?\n", atom1, atom2 ); + // fprintf( stderr, "can bond %6d %6d?\n", atom1, atom2 ); - if( !workspace->restricted[ atom1 ] && !workspace->restricted[ atom2 ] ) - return 1; + if ( !workspace->restricted[ atom1 ] && !workspace->restricted[ atom2 ] ) + return 1; - for( i = 0; i < workspace->restricted[ atom1 ]; ++i ) - if( workspace->restricted_list[ atom1 ][i] == atom2 ) - return 1; + for ( i = 0; i < workspace->restricted[ atom1 ]; ++i ) + if ( workspace->restricted_list[ atom1 ][i] == atom2 ) + return 1; - for( i = 0; i < workspace->restricted[ atom2 ]; ++i ) - if( workspace->restricted_list[ atom2 ][i] == atom1 ) - return 1; + for ( i = 0; i < workspace->restricted[ atom2 ]; ++i ) + if ( workspace->restricted_list[ atom2 ][i] == atom1 ) + return 1; - return 0; + return 0; } /* check if atom2 is on atom1's near neighbor list */ inline int is_Near_Neighbor( list *near_nbrs, int atom1, int atom2 ) { - int i; + int i; - for( i=Start_Index(atom1,near_nbrs); i<End_Index(atom1,near_nbrs); ++i ) - if( near_nbrs->select.near_nbr_list[i].nbr == atom2 ) - { - // fprintf( stderr, "near neighbors %6d %6d\n", atom1, atom2 ); - return 1; - } + for ( i = Start_Index(atom1, near_nbrs); i < End_Index(atom1, near_nbrs); ++i ) + if ( near_nbrs->select.near_nbr_list[i].nbr == atom2 ) + { + // fprintf( stderr, "near neighbors %6d %6d\n", atom1, atom2 ); + return 1; + } - return 0; + return 0; } -void Generate_Neighbor_Lists( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Generate_Neighbor_Lists( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i, j, k; - int x, y, z; - int *nbr_atoms; - int atom1, atom2, max; - int num_far; - int c, count; - int grid_top; - grid *g = &( system->g ); - list *far_nbrs = (*lists) + FAR_NBRS; - //int hb_type1, hb_type2; - //list *hbonds = (*lists) + HBOND; - //int top_hbond1, top_hbond2; - get_far_neighbors_function Get_Far_Neighbors; - far_neighbor_data new_nbrs[125]; + int i, j, k; + int x, y, z; + int *nbr_atoms; + int atom1, atom2, max; + int num_far; + int c, count; + int grid_top; + grid *g = &( system->g ); + list *far_nbrs = (*lists) + FAR_NBRS; + //int hb_type1, hb_type2; + //list *hbonds = (*lists) + HBOND; + //int top_hbond1, top_hbond2; + get_far_neighbors_function Get_Far_Neighbors; + far_neighbor_data new_nbrs[125]; #ifndef REORDER_ATOMS - int l, m; + int l, m; #endif - // fprintf( stderr, "\n\tentered nbrs - " ); - if( control->ensemble == iNPT || control->ensemble == sNPT || - control->ensemble == NPT ) - Update_Grid( system ); - // fprintf( stderr, "grid updated - " ); + // fprintf( stderr, "\n\tentered nbrs - " ); + if ( control->ensemble == iNPT || control->ensemble == sNPT || + control->ensemble == NPT ) + Update_Grid( system ); + // fprintf( stderr, "grid updated - " ); - Bin_Atoms( system, out_control ); - // fprintf( stderr, "atoms sorted - " ); + Bin_Atoms( system, out_control ); + // fprintf( stderr, "atoms sorted - " ); #ifdef REORDER_ATOMS - Cluster_Atoms( system, workspace ); - // fprintf( stderr, "atoms clustered - " ); + Cluster_Atoms( system, workspace ); + // fprintf( stderr, "atoms clustered - " ); #endif - Choose_Neighbor_Finder( system, control, &Get_Far_Neighbors ); - // fprintf( stderr, "function chosen - " ); - - Reset_Neighbor_Lists( system, workspace, lists ); - // fprintf( stderr, "lists cleared - " ); - - num_far = 0; - num_near = 0; - c = 0; - - /* first pick up a cell in the grid */ - for( i = 0; i < g->ncell[0]; i++ ) - for( j = 0; j < g->ncell[1]; j++ ) - for( k = 0; k < g->ncell[2]; k++ ) { - nbrs = g->nbrs[i][j][k]; - nbrs_cp = g->nbrs_cp[i][j][k]; - - /* pick up an atom from the current cell */ - //#ifdef REORDER_ATOMS - // for(atom1 = g->start[i][j][k]; atom1 < g->end[i][j][k]; atom1++) - //#else - for(l = 0; l < g->top[i][j][k]; ++l ){ - atom1 = g->atoms[i][j][k][l]; - Set_End_Index( atom1, num_far, far_nbrs ); - // fprintf( stderr, "atom %d:\n", atom1 ); - - itr = 0; - while( nbrs[itr][0] > 0 ){ - x = nbrs[itr][0]; - y = nbrs[itr][1]; - z = nbrs[itr][2]; - - // if( DistSqr_to_CP(nbrs_cp[itr], system->atoms[atom1].x ) <= - // SQR(control->r_cut)) - nbr_atoms = g->atoms[x][y][z]; - max_atoms = g->top[x][y][z]; - - /* pick up another atom from the neighbor cell - - we have to compare atom1 with its own periodic images as well, - that's why there is also equality in the if stmt below */ - //#ifdef REORDER_ATOMS - //for(atom2=g->start[x][y][z]; atom2<g->end[x][y][z]; atom2++) - //#else - for( m = 0, atom2=nbr_atoms[m]; m < max; ++m, atom2=nbr_atoms[m] ) - if( atom1 >= atom2 ) { - //fprintf( stderr, "\tatom2 %d", atom2 ); - //top_near1 = End_Index( atom1, near_nbrs ); - //Set_Start_Index( atom1, num_far, far_nbrs ); - //hb_type1=system->reaxprm.sbp[system->atoms[atom1].type].p_hbond; - Get_Far_Neighbors( system->atoms[atom1].x, - system->atoms[atom2].x, - &(system->box), control, new_nbrs, &count ); - fprintf( stderr, "\t%d count:%d\n", atom2, count ); - - for( c = 0; c < count; ++c ) - if(atom1 != atom2 || (atom1 == atom2 && new_nbrs[c].d>=0.1)){ - Set_Far_Neighbor(&(far_nbrs->select.far_nbr_list[num_far]), - atom2, new_nbrs[c].d, 1.0, - new_nbrs[c].dvec, new_nbrs[c].rel_box ); - ++num_far; - - /*fprintf(stderr,"FARNBR:%6d%6d%8.3f[%8.3f%8.3f%8.3f]\n", - atom1, atom2, new_nbrs[c].d, - new_nbrs[c].dvec[0], new_nbrs[c].dvec[1], - new_nbrs[c].dvec[2] ); */ - - - /* hydrogen bond lists */ - /*if( control->hb_cut > 0.1 && - new_nbrs[c].d <= control->hb_cut ) { - // fprintf( stderr, "%d %d\n", atom1, atom2 ); - hb_type2=system->reaxprm.sbp[system->atoms[atom2].type].p_hbond; - if( hb_type1 == 1 && hb_type2 == 2 ) { - top_hbond1=End_Index(workspace->hbond_index[atom1],hbonds); - Set_Near_Neighbor(&(hbonds->select.hbond_list[top_hbond1]), - atom2, new_nbrs[c].d, 1.0, new_nbrs[c].dvec, - new_nbrs[c].rel_box ); - Set_End_Index( workspace->hbond_index[atom1], - top_hbond1 + 1, hbonds ); - } - else if( hb_type1 == 2 && hb_type2 == 1 ) { - top_hbond2 = End_Index( workspace->hbond_index[atom2], hbonds ); - Set_Near_Neighbor(&(hbonds->select.hbond_list[top_hbond2]), - atom1, new_nbrs[c].d, -1.0, new_nbrs[c].dvec, - new_nbrs[c].rel_box ); - Set_End_Index( workspace->hbond_index[atom2], - top_hbond2 + 1, hbonds ); - }*/ - } - } - } - - Set_End_Index( atom1, top_far1, far_nbrs ); - } - } - - - fprintf( stderr, "nbrs done-" ); - - - /* apply restrictions on near neighbors only */ - if( (data->step - data->prev_steps) < control->restrict_bonds ) { - for( atom1 = 0; atom1 < system->N; ++atom1 ) - if( workspace->restricted[ atom1 ] ) { - // fprintf( stderr, "atom1: %d\n", atom1 ); - - top_near1 = End_Index( atom1, near_nbrs ); - - for( j = 0; j < workspace->restricted[ atom1 ]; ++j ) - if(!is_Near_Neighbor(near_nbrs, atom1, - atom2 = workspace->restricted_list[atom1][j])) { - fprintf( stderr, "%3d-%3d: added bond by applying restrictions!\n", - atom1, atom2 ); - - top_near2 = End_Index( atom2, near_nbrs ); - - /* we just would like to get the nearest image, so a call to - Get_Periodic_Far_Neighbors_Big_Box is good enough. */ - Get_Periodic_Far_Neighbors_Big_Box( system->atoms[ atom1 ].x, - system->atoms[ atom2 ].x, - &(system->box), control, - new_nbrs, &count ); - - Set_Near_Neighbor( &(near_nbrs->select.near_nbr_list[ top_near1 ]), - atom2, new_nbrs[c].d, 1.0, - new_nbrs[c].dvec, new_nbrs[c].rel_box ); - ++top_near1; - - Set_Near_Neighbor( &(near_nbrs->select.near_nbr_list[ top_near2 ]), - atom1, new_nbrs[c].d, -1.0, - new_nbrs[c].dvec, new_nbrs[c].rel_box ); - Set_End_Index( atom2, top_near2+1, near_nbrs ); - } - - Set_End_Index( atom1, top_near1, near_nbrs ); - } - } - // fprintf( stderr, "restrictions applied-" ); - - - /* verify nbrlists, count num_intrs, sort nearnbrs */ - near_nbrs->num_intrs = 0; - far_nbrs->num_intrs = 0; - for( i = 0; i < system->N-1; ++i ) { - if( End_Index(i, near_nbrs) > Start_Index(i+1, near_nbrs) ) { - fprintf( stderr, - "step%3d: nearnbr list of atom%d is overwritten by atom%d\n", - data->step, i+1, i ); - exit( 1 ); + Choose_Neighbor_Finder( system, control, &Get_Far_Neighbors ); + // fprintf( stderr, "function chosen - " ); + + Reset_Neighbor_Lists( system, workspace, lists ); + // fprintf( stderr, "lists cleared - " ); + + num_far = 0; + num_near = 0; + c = 0; + + /* first pick up a cell in the grid */ + for ( i = 0; i < g->ncell[0]; i++ ) + for ( j = 0; j < g->ncell[1]; j++ ) + for ( k = 0; k < g->ncell[2]; k++ ) + { + nbrs = g->nbrs[i][j][k]; + nbrs_cp = g->nbrs_cp[i][j][k]; + + /* pick up an atom from the current cell */ + //#ifdef REORDER_ATOMS + // for(atom1 = g->start[i][j][k]; atom1 < g->end[i][j][k]; atom1++) + //#else + for (l = 0; l < g->top[i][j][k]; ++l ) + { + atom1 = g->atoms[i][j][k][l]; + Set_End_Index( atom1, num_far, far_nbrs ); + // fprintf( stderr, "atom %d:\n", atom1 ); + + itr = 0; + while ( nbrs[itr][0] > 0 ) + { + x = nbrs[itr][0]; + y = nbrs[itr][1]; + z = nbrs[itr][2]; + + // if( DistSqr_to_CP(nbrs_cp[itr], system->atoms[atom1].x ) <= + // SQR(control->r_cut)) + nbr_atoms = g->atoms[x][y][z]; + max_atoms = g->top[x][y][z]; + + /* pick up another atom from the neighbor cell - + we have to compare atom1 with its own periodic images as well, + that's why there is also equality in the if stmt below */ + //#ifdef REORDER_ATOMS + //for(atom2=g->start[x][y][z]; atom2<g->end[x][y][z]; atom2++) + //#else + for ( m = 0, atom2 = nbr_atoms[m]; m < max; ++m, atom2 = nbr_atoms[m] ) + if ( atom1 >= atom2 ) + { + //fprintf( stderr, "\tatom2 %d", atom2 ); + //top_near1 = End_Index( atom1, near_nbrs ); + //Set_Start_Index( atom1, num_far, far_nbrs ); + //hb_type1=system->reaxprm.sbp[system->atoms[atom1].type].p_hbond; + Get_Far_Neighbors( system->atoms[atom1].x, + system->atoms[atom2].x, + &(system->box), control, new_nbrs, &count ); + fprintf( stderr, "\t%d count:%d\n", atom2, count ); + + for ( c = 0; c < count; ++c ) + if (atom1 != atom2 || (atom1 == atom2 && new_nbrs[c].d >= 0.1)) + { + Set_Far_Neighbor(&(far_nbrs->select.far_nbr_list[num_far]), + atom2, new_nbrs[c].d, 1.0, + new_nbrs[c].dvec, new_nbrs[c].rel_box ); + ++num_far; + + /*fprintf(stderr,"FARNBR:%6d%6d%8.3f[%8.3f%8.3f%8.3f]\n", + atom1, atom2, new_nbrs[c].d, + new_nbrs[c].dvec[0], new_nbrs[c].dvec[1], + new_nbrs[c].dvec[2] ); */ + + + /* hydrogen bond lists */ + /*if( control->hb_cut > 0.1 && + new_nbrs[c].d <= control->hb_cut ) { + // fprintf( stderr, "%d %d\n", atom1, atom2 ); + hb_type2=system->reaxprm.sbp[system->atoms[atom2].type].p_hbond; + if( hb_type1 == 1 && hb_type2 == 2 ) { + top_hbond1=End_Index(workspace->hbond_index[atom1],hbonds); + Set_Near_Neighbor(&(hbonds->select.hbond_list[top_hbond1]), + atom2, new_nbrs[c].d, 1.0, new_nbrs[c].dvec, + new_nbrs[c].rel_box ); + Set_End_Index( workspace->hbond_index[atom1], + top_hbond1 + 1, hbonds ); + } + else if( hb_type1 == 2 && hb_type2 == 1 ) { + top_hbond2 = End_Index( workspace->hbond_index[atom2], hbonds ); + Set_Near_Neighbor(&(hbonds->select.hbond_list[top_hbond2]), + atom1, new_nbrs[c].d, -1.0, new_nbrs[c].dvec, + new_nbrs[c].rel_box ); + Set_End_Index( workspace->hbond_index[atom2], + top_hbond2 + 1, hbonds ); + }*/ + } + } + } + + Set_End_Index( atom1, top_far1, far_nbrs ); + } + } + + + fprintf( stderr, "nbrs done-" ); + + + /* apply restrictions on near neighbors only */ + if ( (data->step - data->prev_steps) < control->restrict_bonds ) + { + for ( atom1 = 0; atom1 < system->N; ++atom1 ) + if ( workspace->restricted[ atom1 ] ) + { + // fprintf( stderr, "atom1: %d\n", atom1 ); + + top_near1 = End_Index( atom1, near_nbrs ); + + for ( j = 0; j < workspace->restricted[ atom1 ]; ++j ) + if (!is_Near_Neighbor(near_nbrs, atom1, + atom2 = workspace->restricted_list[atom1][j])) + { + fprintf( stderr, "%3d-%3d: added bond by applying restrictions!\n", + atom1, atom2 ); + + top_near2 = End_Index( atom2, near_nbrs ); + + /* we just would like to get the nearest image, so a call to + Get_Periodic_Far_Neighbors_Big_Box is good enough. */ + Get_Periodic_Far_Neighbors_Big_Box( system->atoms[ atom1 ].x, + system->atoms[ atom2 ].x, + &(system->box), control, + new_nbrs, &count ); + + Set_Near_Neighbor( &(near_nbrs->select.near_nbr_list[ top_near1 ]), + atom2, new_nbrs[c].d, 1.0, + new_nbrs[c].dvec, new_nbrs[c].rel_box ); + ++top_near1; + + Set_Near_Neighbor( &(near_nbrs->select.near_nbr_list[ top_near2 ]), + atom1, new_nbrs[c].d, -1.0, + new_nbrs[c].dvec, new_nbrs[c].rel_box ); + Set_End_Index( atom2, top_near2 + 1, near_nbrs ); + } + + Set_End_Index( atom1, top_near1, near_nbrs ); + } + } + // fprintf( stderr, "restrictions applied-" ); + + + /* verify nbrlists, count num_intrs, sort nearnbrs */ + near_nbrs->num_intrs = 0; + far_nbrs->num_intrs = 0; + for ( i = 0; i < system->N - 1; ++i ) + { + if ( End_Index(i, near_nbrs) > Start_Index(i + 1, near_nbrs) ) + { + fprintf( stderr, + "step%3d: nearnbr list of atom%d is overwritten by atom%d\n", + data->step, i + 1, i ); + exit( 1 ); + } + + near_nbrs->num_intrs += Num_Entries(i, near_nbrs); + + if ( End_Index(i, far_nbrs) > Start_Index(i + 1, far_nbrs) ) + { + fprintf( stderr, + "step%3d: farnbr list of atom%d is overwritten by atom%d\n", + data->step, i + 1, i ); + exit( 1 ); + } + + far_nbrs->num_intrs += Num_Entries(i, far_nbrs); } - - near_nbrs->num_intrs += Num_Entries(i, near_nbrs); - - if( End_Index(i, far_nbrs) > Start_Index(i+1, far_nbrs) ) { - fprintf( stderr, - "step%3d: farnbr list of atom%d is overwritten by atom%d\n", - data->step, i+1, i ); - exit( 1 ); + + for ( i = 0; i < system->N; ++i ) + { + qsort( &(near_nbrs->select.near_nbr_list[ Start_Index(i, near_nbrs) ]), + Num_Entries(i, near_nbrs), sizeof(near_neighbor_data), + compare_near_nbrs ); } - - far_nbrs->num_intrs += Num_Entries(i, far_nbrs); - } - - for( i = 0; i < system->N; ++i ) { - qsort( &(near_nbrs->select.near_nbr_list[ Start_Index(i, near_nbrs) ]), - Num_Entries(i, near_nbrs), sizeof(near_neighbor_data), - compare_near_nbrs ); - } - // fprintf( stderr, "near nbrs sorted\n" ); - + // fprintf( stderr, "near nbrs sorted\n" ); + #ifdef TEST_ENERGY - /* for( i = 0; i < system->N; ++i ) { - qsort( &(far_nbrs->select.far_nbr_list[ Start_Index(i, far_nbrs) ]), - Num_Entries(i, far_nbrs), sizeof(far_neighbor_data), - compare_far_nbrs ); - } */ - - fprintf( stderr, "Near neighbors/atom: %d (compare to 150)\n", - num_near / system->N ); - fprintf( stderr, "Far neighbors per atom: %d (compare to %d)\n", - num_far / system->N, control->max_far_nbrs ); + /* for( i = 0; i < system->N; ++i ) { + qsort( &(far_nbrs->select.far_nbr_list[ Start_Index(i, far_nbrs) ]), + Num_Entries(i, far_nbrs), sizeof(far_neighbor_data), + compare_far_nbrs ); + } */ + + fprintf( stderr, "Near neighbors/atom: %d (compare to 150)\n", + num_near / system->N ); + fprintf( stderr, "Far neighbors per atom: %d (compare to %d)\n", + num_far / system->N, control->max_far_nbrs ); #endif - - //fprintf( stderr, "step%d: num of nearnbrs = %6d num of farnbrs: %6d\n", - // data->step, num_near, num_far ); - //fprintf( stderr, "\talloc nearnbrs = %6d alloc farnbrs: %6d\n", - // system->N * near_nbrs->intrs_per_unit, - // system->N * far_nbrs->intrs_per_unit ); + //fprintf( stderr, "step%d: num of nearnbrs = %6d num of farnbrs: %6d\n", + // data->step, num_near, num_far ); + + //fprintf( stderr, "\talloc nearnbrs = %6d alloc farnbrs: %6d\n", + // system->N * near_nbrs->intrs_per_unit, + // system->N * far_nbrs->intrs_per_unit ); } -void Generate_Neighbor_Lists( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Generate_Neighbor_Lists( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i, j, k, l, m, itr; - int x, y, z; - int atom1, atom2, max; - int num_far, c, count; - int *nbr_atoms; - ivec *nbrs; - rvec *nbrs_cp; - grid *g; - list *far_nbrs; - get_far_neighbors_function Get_Far_Neighbors; - far_neighbor_data new_nbrs[125]; - - g = &( system->g ); - far_nbrs = (*lists) + FAR_NBRS; - - // fprintf( stderr, "\n\tentered nbrs - " ); - if( control->ensemble == iNPT || - control->ensemble == sNPT || - control->ensemble == NPT ) - Update_Grid( system ); - // fprintf( stderr, "grid updated - " ); - - Bin_Atoms( system, out_control ); - // fprintf( stderr, "atoms sorted - " ); - Choose_Neighbor_Finder( system, control, &Get_Far_Neighbors ); - // fprintf( stderr, "function chosen - " ); - Reset_Neighbor_Lists( system, workspace, lists ); - // fprintf( stderr, "lists cleared - " ); - - num_far = 0; - c = 0; - - /* first pick up a cell in the grid */ - for( i = 0; i < g->ncell[0]; i++ ) - for( j = 0; j < g->ncell[1]; j++ ) - for( k = 0; k < g->ncell[2]; k++ ) { - nbrs = g->nbrs[i][j][k]; - nbrs_cp = g->nbrs_cp[i][j][k]; - fprintf( stderr, "gridcell %d %d %d\n", i, j, k ); - - /* pick up an atom from the current cell */ - for(l = 0; l < g->top[i][j][k]; ++l ){ - atom1 = g->atoms[i][j][k][l]; - Set_Start_Index( atom1, num_far, far_nbrs ); - fprintf( stderr, "\tatom %d\n", atom1 ); - - itr = 0; - while( nbrs[itr][0] > 0 ){ - x = nbrs[itr][0]; - y = nbrs[itr][1]; - z = nbrs[itr][2]; - fprintf( stderr, "\t\tgridcell %d %d %d\n", x, y, z ); - - // if( DistSqr_to_CP(nbrs_cp[itr], system->atoms[atom1].x ) <= - // SQR(control->r_cut)) - nbr_atoms = g->atoms[x][y][z]; - max = g->top[x][y][z]; - fprintf( stderr, "\t\tmax: %d\n", max ); - - - /* pick up another atom from the neighbor cell - - we have to compare atom1 with its own periodic images as well, - that's why there is also equality in the if stmt below */ - for( m = 0, atom2=nbr_atoms[m]; m < max; ++m, atom2=nbr_atoms[m] ) - if( atom1 >= atom2 ) { - Get_Far_Neighbors( system->atoms[atom1].x, - system->atoms[atom2].x, - &(system->box), control, new_nbrs, &count ); - fprintf( stderr, "\t\t\t%d count:%d\n", atom2, count ); - - for( c = 0; c < count; ++c ) - if(atom1 != atom2 || (atom1 == atom2 && new_nbrs[c].d>=0.1)){ - Set_Far_Neighbor(&(far_nbrs->select.far_nbr_list[num_far]), - atom2, new_nbrs[c].d, 1.0, - new_nbrs[c].dvec, new_nbrs[c].rel_box ); - ++num_far; - - /*fprintf(stderr,"FARNBR:%6d%6d%8.3f[%8.3f%8.3f%8.3f]\n", - atom1, atom2, new_nbrs[c].d, - new_nbrs[c].dvec[0], new_nbrs[c].dvec[1], - new_nbrs[c].dvec[2] ); */ - } - } - - ++itr; - } - - Set_End_Index( atom1, num_far, far_nbrs ); - } - } - - far_nbrs->num_intrs = num_far; - fprintf( stderr, "nbrs done, num_far: %d\n", num_far ); + int i, j, k, l, m, itr; + int x, y, z; + int atom1, atom2, max; + int num_far, c, count; + int *nbr_atoms; + ivec *nbrs; + rvec *nbrs_cp; + grid *g; + list *far_nbrs; + get_far_neighbors_function Get_Far_Neighbors; + far_neighbor_data new_nbrs[125]; + + g = &( system->g ); + far_nbrs = (*lists) + FAR_NBRS; + + // fprintf( stderr, "\n\tentered nbrs - " ); + if ( control->ensemble == iNPT || + control->ensemble == sNPT || + control->ensemble == NPT ) + Update_Grid( system ); + // fprintf( stderr, "grid updated - " ); + + Bin_Atoms( system, out_control ); + // fprintf( stderr, "atoms sorted - " ); + Choose_Neighbor_Finder( system, control, &Get_Far_Neighbors ); + // fprintf( stderr, "function chosen - " ); + Reset_Neighbor_Lists( system, workspace, lists ); + // fprintf( stderr, "lists cleared - " ); + + num_far = 0; + c = 0; + + /* first pick up a cell in the grid */ + for ( i = 0; i < g->ncell[0]; i++ ) + for ( j = 0; j < g->ncell[1]; j++ ) + for ( k = 0; k < g->ncell[2]; k++ ) + { + nbrs = g->nbrs[i][j][k]; + nbrs_cp = g->nbrs_cp[i][j][k]; + fprintf( stderr, "gridcell %d %d %d\n", i, j, k ); + + /* pick up an atom from the current cell */ + for (l = 0; l < g->top[i][j][k]; ++l ) + { + atom1 = g->atoms[i][j][k][l]; + Set_Start_Index( atom1, num_far, far_nbrs ); + fprintf( stderr, "\tatom %d\n", atom1 ); + + itr = 0; + while ( nbrs[itr][0] > 0 ) + { + x = nbrs[itr][0]; + y = nbrs[itr][1]; + z = nbrs[itr][2]; + fprintf( stderr, "\t\tgridcell %d %d %d\n", x, y, z ); + + // if( DistSqr_to_CP(nbrs_cp[itr], system->atoms[atom1].x ) <= + // SQR(control->r_cut)) + nbr_atoms = g->atoms[x][y][z]; + max = g->top[x][y][z]; + fprintf( stderr, "\t\tmax: %d\n", max ); + + + /* pick up another atom from the neighbor cell - + we have to compare atom1 with its own periodic images as well, + that's why there is also equality in the if stmt below */ + for ( m = 0, atom2 = nbr_atoms[m]; m < max; ++m, atom2 = nbr_atoms[m] ) + if ( atom1 >= atom2 ) + { + Get_Far_Neighbors( system->atoms[atom1].x, + system->atoms[atom2].x, + &(system->box), control, new_nbrs, &count ); + fprintf( stderr, "\t\t\t%d count:%d\n", atom2, count ); + + for ( c = 0; c < count; ++c ) + if (atom1 != atom2 || (atom1 == atom2 && new_nbrs[c].d >= 0.1)) + { + Set_Far_Neighbor(&(far_nbrs->select.far_nbr_list[num_far]), + atom2, new_nbrs[c].d, 1.0, + new_nbrs[c].dvec, new_nbrs[c].rel_box ); + ++num_far; + + /*fprintf(stderr,"FARNBR:%6d%6d%8.3f[%8.3f%8.3f%8.3f]\n", + atom1, atom2, new_nbrs[c].d, + new_nbrs[c].dvec[0], new_nbrs[c].dvec[1], + new_nbrs[c].dvec[2] ); */ + } + } + + ++itr; + } + + Set_End_Index( atom1, num_far, far_nbrs ); + } + } + + far_nbrs->num_intrs = num_far; + fprintf( stderr, "nbrs done, num_far: %d\n", num_far ); #if defined(DEBUG) - for( i = 0; i < system->N; ++i ) { - qsort( &(far_nbrs->select.far_nbr_list[ Start_Index(i, far_nbrs) ]), - Num_Entries(i, far_nbrs), sizeof(far_neighbor_data), - compare_far_nbrs ); - } - - fprintf( stderr, "step%d: num of farnbrs=%6d\n", data->step, num_far ); - fprintf( stderr, "\tallocated farnbrs: %6d\n", - system->N * far_nbrs->intrs_per_unit ); + for ( i = 0; i < system->N; ++i ) + { + qsort( &(far_nbrs->select.far_nbr_list[ Start_Index(i, far_nbrs) ]), + Num_Entries(i, far_nbrs), sizeof(far_neighbor_data), + compare_far_nbrs ); + } + + fprintf( stderr, "step%d: num of farnbrs=%6d\n", data->step, num_far ); + fprintf( stderr, "\tallocated farnbrs: %6d\n", + system->N * far_nbrs->intrs_per_unit ); #endif } - + #endif diff --git a/puremd_rc_1003/sPuReMD/neighbors.h b/puremd_rc_1003/sPuReMD/neighbors.h index bca35b82..e849b1e4 100644 --- a/puremd_rc_1003/sPuReMD/neighbors.h +++ b/puremd_rc_1003/sPuReMD/neighbors.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -25,8 +25,8 @@ #include "mytypes.h" void Generate_Neighbor_Lists( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); + static_storage*, list**, output_controls* ); -int Estimate_NumNeighbors( reax_system*, control_params*, - static_storage*, list** ); +int Estimate_NumNeighbors( reax_system*, control_params*, + static_storage*, list** ); #endif diff --git a/puremd_rc_1003/sPuReMD/param.c b/puremd_rc_1003/sPuReMD/param.c index 045e97bc..96945274 100644 --- a/puremd_rc_1003/sPuReMD/param.c +++ b/puremd_rc_1003/sPuReMD/param.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -26,1184 +26,1296 @@ int Get_Atom_Type( reax_interaction *reaxprm, char *s ) { - int i; + int i; - for( i = 0; i < reaxprm->num_atom_types; ++i ) - if( !strcmp( reaxprm->sbp[i].name, s ) ) - return i; + for ( i = 0; i < reaxprm->num_atom_types; ++i ) + if ( !strcmp( reaxprm->sbp[i].name, s ) ) + return i; - fprintf( stderr, "Unknown atom type %s. Terminating...\n", s ); - exit( UNKNOWN_ATOM_TYPE_ERR ); + fprintf( stderr, "Unknown atom type %s. Terminating...\n", s ); + exit( UNKNOWN_ATOM_TYPE_ERR ); } int Tokenize(char* s, char*** tok) { - char test[MAX_LINE]; - char *sep = "\t \n!="; - char *word; - int count=0; + char test[MAX_LINE]; + char *sep = "\t \n!="; + char *word; + int count = 0; + + strncpy( test, s, MAX_LINE ); - strncpy( test, s, MAX_LINE ); + // fprintf( stderr, "|%s|\n", test ); - // fprintf( stderr, "|%s|\n", test ); - - for( word = strtok(test, sep); word; word = strtok(NULL, sep) ) + for ( word = strtok(test, sep); word; word = strtok(NULL, sep) ) { - strncpy( (*tok)[count], word, MAX_LINE ); - count++; + strncpy( (*tok)[count], word, MAX_LINE ); + count++; } - return count; + return count; } /* Initialize Taper params */ void Init_Taper( control_params *control ) { - real d1, d7; - real swa, swa2, swa3; - real swb, swb2, swb3; + real d1, d7; + real swa, swa2, swa3; + real swb, swb2, swb3; - swa = control->r_low; - swb = control->r_cut; + swa = control->r_low; + swb = control->r_cut; - if( fabs( swa ) > 0.01 ) - fprintf( stderr,"Warning: non-zero value for lower Taper-radius cutoff\n" ); - - if( swb < 0 ) + if ( fabs( swa ) > 0.01 ) + fprintf( stderr, "Warning: non-zero value for lower Taper-radius cutoff\n" ); + + if ( swb < 0 ) { - fprintf( stderr, "Negative value for upper Taper-radius cutoff\n" ); - exit( INVALID_INPUT ); - } - else if( swb < 5 ) - fprintf( stderr,"Warning: low value for upper Taper-radius cutoff:%f\n", - swb ); - - d1 = swb - swa; - d7 = POW( d1, 7.0 ); - swa2 = SQR( swa ); - swa3 = CUBE( swa ); - swb2 = SQR( swb ); - swb3 = CUBE( swb ); - - control->Tap7 = 20.0 / d7; - control->Tap6 = -70.0 * (swa + swb) / d7; - control->Tap5 = 84.0 * (swa2 + 3.0*swa*swb + swb2) / d7; - control->Tap4 = -35.0 * (swa3 + 9.0*swa2*swb + 9.0*swa*swb2 + swb3 ) / d7; - control->Tap3 = 140.0 * (swa3*swb + 3.0*swa2*swb2 + swa*swb3 ) / d7; - control->Tap2 =-210.0 * (swa3*swb2 + swa2*swb3) / d7; - control->Tap1 = 140.0 * swa3 * swb3 / d7; - control->Tap0 = (-35.0*swa3*swb2*swb2 + 21.0*swa2*swb3*swb2 + - 7.0*swa*swb3*swb3 + swb3*swb3*swb ) / d7; + fprintf( stderr, "Negative value for upper Taper-radius cutoff\n" ); + exit( INVALID_INPUT ); + } + else if ( swb < 5 ) + fprintf( stderr, "Warning: low value for upper Taper-radius cutoff:%f\n", + swb ); + + d1 = swb - swa; + d7 = POW( d1, 7.0 ); + swa2 = SQR( swa ); + swa3 = CUBE( swa ); + swb2 = SQR( swb ); + swb3 = CUBE( swb ); + + control->Tap7 = 20.0 / d7; + control->Tap6 = -70.0 * (swa + swb) / d7; + control->Tap5 = 84.0 * (swa2 + 3.0 * swa * swb + swb2) / d7; + control->Tap4 = -35.0 * (swa3 + 9.0 * swa2 * swb + 9.0 * swa * swb2 + swb3 ) / d7; + control->Tap3 = 140.0 * (swa3 * swb + 3.0 * swa2 * swb2 + swa * swb3 ) / d7; + control->Tap2 = -210.0 * (swa3 * swb2 + swa2 * swb3) / d7; + control->Tap1 = 140.0 * swa3 * swb3 / d7; + control->Tap0 = (-35.0 * swa3 * swb2 * swb2 + 21.0 * swa2 * swb3 * swb2 + + 7.0 * swa * swb3 * swb3 + swb3 * swb3 * swb ) / d7; } char Read_Force_Field( FILE* fp, reax_interaction* reax ) { - char *s; - char **tmp; - char ****tor_flag; - int c, i, j, k, l, m, n, o, p, cnt; - real val; - - s = (char*) malloc(sizeof(char)*MAX_LINE); - tmp = (char**) malloc(sizeof(char*)*MAX_TOKENS); - for (i=0; i < MAX_TOKENS; i++) - tmp[i] = (char*) malloc(sizeof(char)*MAX_TOKEN_LEN); - - - /* reading first header comment */ - fgets( s, MAX_LINE, fp ); - - - /* line 2 is number of global parameters */ - fgets( s, MAX_LINE, fp ); - c = Tokenize( s, &tmp ); - - /* reading the number of global parameters */ - n = atoi(tmp[0]); - if (n < 1) - { - fprintf( stderr, "WARNING: number of globals in ffield file is 0!\n" ); - return 1; - } + char *s; + char **tmp; + char ****tor_flag; + int c, i, j, k, l, m, n, o, p, cnt; + real val; - reax->gp.n_global = n; - reax->gp.l = (real*) malloc(sizeof(real)*n); + s = (char*) malloc(sizeof(char) * MAX_LINE); + tmp = (char**) malloc(sizeof(char*)*MAX_TOKENS); + for (i = 0; i < MAX_TOKENS; i++) + tmp[i] = (char*) malloc(sizeof(char) * MAX_TOKEN_LEN); - /* see mytypes.h for mapping between l[i] and the lambdas used in ff */ - for (i=0; i < n; i++) - { - fgets(s,MAX_LINE,fp); - c=Tokenize(s,&tmp); - - val = (real) atof(tmp[0]); - reax->gp.l[i] = val; + /* reading first header comment */ + fgets( s, MAX_LINE, fp ); + + + /* line 2 is number of global parameters */ + fgets( s, MAX_LINE, fp ); + c = Tokenize( s, &tmp ); + + /* reading the number of global parameters */ + n = atoi(tmp[0]); + if (n < 1) + { + fprintf( stderr, "WARNING: number of globals in ffield file is 0!\n" ); + return 1; } + reax->gp.n_global = n; + reax->gp.l = (real*) malloc(sizeof(real) * n); - /* next line is number of atom types and some comments */ - fgets( s, MAX_LINE, fp ); - c = Tokenize( s, &tmp ); - reax->num_atom_types = atoi(tmp[0]); - - - /* 3 lines of comments */ - 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*) - calloc( reax->num_atom_types, sizeof(single_body_parameters) ); - reax->tbp = (two_body_parameters**) - calloc( reax->num_atom_types, sizeof(two_body_parameters*) ); - reax->thbp= (three_body_header***) - calloc( reax->num_atom_types, sizeof(three_body_header**) ); - reax->hbp = (hbond_parameters***) - calloc( reax->num_atom_types, sizeof(hbond_parameters**) ); - reax->fbp = (four_body_header****) - calloc( reax->num_atom_types, sizeof(four_body_header***) ); - tor_flag = (char****) - calloc( reax->num_atom_types, sizeof(char***) ); - - for( i = 0; i < reax->num_atom_types; i++ ) + /* see mytypes.h for mapping between l[i] and the lambdas used in ff */ + for (i = 0; i < n; i++) { - reax->tbp[i] = (two_body_parameters*) - calloc( reax->num_atom_types, sizeof(two_body_parameters) ); - reax->thbp[i]= (three_body_header**) - calloc( reax->num_atom_types, sizeof(three_body_header*) ); - reax->hbp[i] = (hbond_parameters**) - calloc( reax->num_atom_types, sizeof(hbond_parameters*) ); - reax->fbp[i] = (four_body_header***) - calloc( reax->num_atom_types, sizeof(four_body_header**) ); - tor_flag[i] = (char***) - calloc( reax->num_atom_types, sizeof(char**) ); - - for( j = 0; j < reax->num_atom_types; j++ ) - { - reax->thbp[i][j]= (three_body_header*) - calloc( reax->num_atom_types, sizeof(three_body_header) ); - reax->hbp[i][j] = (hbond_parameters*) - calloc( reax->num_atom_types, sizeof(hbond_parameters) ); - reax->fbp[i][j] = (four_body_header**) - calloc( reax->num_atom_types, sizeof(four_body_header*) ); - tor_flag[i][j] = (char**) - calloc( reax->num_atom_types, sizeof(char*) ); - - for (k=0; k < reax->num_atom_types; k++) - { - reax->fbp[i][j][k] = (four_body_header*) - calloc( reax->num_atom_types, sizeof(four_body_header) ); - tor_flag[i][j][k] = (char*) - calloc( reax->num_atom_types, sizeof(char) ); - } - } + fgets(s, MAX_LINE, fp); + c = Tokenize(s, &tmp); + + val = (real) atof(tmp[0]); + + reax->gp.l[i] = val; } - // vdWaals type: 1: Shielded Morse, no inner-wall - // 2: inner wall, no shielding - // 3: inner wall+shielding - reax->gp.vdw_type = 0; - - /* reading single atom parameters */ - /* there are 4 lines of each single atom parameters in ff files. these - parameters later determine some of the pair and triplet parameters using - combination rules. */ - for( i = 0; i < reax->num_atom_types; i++ ) { - /* line one */ - fgets( s, MAX_LINE, fp ); - c = Tokenize( s, &tmp ); - - for( j = 0; j < strlen( tmp[0] ); ++j ) - reax->sbp[i].name[j] = toupper( tmp[0][j] ); - - val = atof(tmp[1]); reax->sbp[i].r_s = val; - val = atof(tmp[2]); reax->sbp[i].valency = val; - val = atof(tmp[3]); reax->sbp[i].mass = val; - val = atof(tmp[4]); reax->sbp[i].r_vdw = val; - val = atof(tmp[5]); reax->sbp[i].epsilon = val; - val = atof(tmp[6]); reax->sbp[i].gamma = val; - val = atof(tmp[7]); reax->sbp[i].r_pi = val; - val = atof(tmp[8]); reax->sbp[i].valency_e = val; - reax->sbp[i].nlp_opt = 0.5*(reax->sbp[i].valency_e-reax->sbp[i].valency); - - /* line two */ - fgets( s, MAX_LINE, fp ); - c = Tokenize( s, &tmp ); - - val = atof(tmp[0]); reax->sbp[i].alpha = val; - val = atof(tmp[1]); reax->sbp[i].gamma_w = val; - val = atof(tmp[2]); reax->sbp[i].valency_boc= val; - val = atof(tmp[3]); reax->sbp[i].p_ovun5 = val; - val = atof(tmp[4]); - val = atof(tmp[5]); reax->sbp[i].chi = val; - val = atof(tmp[6]); reax->sbp[i].eta = 2.0 * val; - /* this is the parameter that is used to determine - which type of atoms participate in h-bonds. - 1 is for H - 2 for O, N, S - 0 for all others.*/ - val = atof(tmp[7]); reax->sbp[i].p_hbond = (int)(val+0.1); - //0.1 is to avoid from truncating down! - - /* line 3 */ - fgets( s, MAX_LINE, fp ); - c = Tokenize( s, &tmp ); - - val = atof(tmp[0]); reax->sbp[i].r_pi_pi = val; - val = atof(tmp[1]); reax->sbp[i].p_lp2 = val; - val = atof(tmp[2]); - val = atof(tmp[3]); reax->sbp[i].b_o_131 = val; - val = atof(tmp[4]); reax->sbp[i].b_o_132 = val; - val = atof(tmp[5]); reax->sbp[i].b_o_133 = val; - val = atof(tmp[6]); - val = atof(tmp[7]); - - /* line 4 */ + + /* next line is number of atom types and some comments */ fgets( s, MAX_LINE, fp ); c = Tokenize( s, &tmp ); - - val = atof(tmp[0]); reax->sbp[i].p_ovun2 = val; - val = atof(tmp[1]); reax->sbp[i].p_val3 = val; - val = atof(tmp[2]); - val = atof(tmp[3]); reax->sbp[i].valency_val= val; - val = atof(tmp[4]); reax->sbp[i].p_val5 = val; - val = atof(tmp[5]); reax->sbp[i].rcore2 = val; - val = atof(tmp[6]); reax->sbp[i].ecore2 = val; - val = atof(tmp[7]); reax->sbp[i].acore2 = val; - - if( reax->sbp[i].rcore2>0.01 && reax->sbp[i].acore2>0.01 ){ // Inner-wall - if( reax->sbp[i].gamma_w>0.5 ){ // Shielding vdWaals - if( reax->gp.vdw_type != 0 && reax->gp.vdw_type != 3 ) - fprintf( stderr, "Warning: inconsistent vdWaals-parameters\n" \ - "Force field parameters for element %s\n" \ - "indicate inner wall+shielding, but earlier\n" \ - "atoms indicate different vdWaals-method.\n" \ - "This may cause division-by-zero errors.\n" \ - "Keeping vdWaals-setting for earlier atoms.\n", - reax->sbp[i].name ); - else{ - reax->gp.vdw_type = 3; + reax->num_atom_types = atoi(tmp[0]); + + + /* 3 lines of comments */ + 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*) + calloc( reax->num_atom_types, sizeof(single_body_parameters) ); + reax->tbp = (two_body_parameters**) + calloc( reax->num_atom_types, sizeof(two_body_parameters*) ); + reax->thbp = (three_body_header***) + calloc( reax->num_atom_types, sizeof(three_body_header**) ); + reax->hbp = (hbond_parameters***) + calloc( reax->num_atom_types, sizeof(hbond_parameters**) ); + reax->fbp = (four_body_header****) + calloc( reax->num_atom_types, sizeof(four_body_header***) ); + tor_flag = (char****) + calloc( reax->num_atom_types, sizeof(char***) ); + + for ( i = 0; i < reax->num_atom_types; i++ ) + { + reax->tbp[i] = (two_body_parameters*) + calloc( reax->num_atom_types, sizeof(two_body_parameters) ); + reax->thbp[i] = (three_body_header**) + calloc( reax->num_atom_types, sizeof(three_body_header*) ); + reax->hbp[i] = (hbond_parameters**) + calloc( reax->num_atom_types, sizeof(hbond_parameters*) ); + reax->fbp[i] = (four_body_header***) + calloc( reax->num_atom_types, sizeof(four_body_header**) ); + tor_flag[i] = (char***) + calloc( reax->num_atom_types, sizeof(char**) ); + + for ( j = 0; j < reax->num_atom_types; j++ ) + { + reax->thbp[i][j] = (three_body_header*) + calloc( reax->num_atom_types, sizeof(three_body_header) ); + reax->hbp[i][j] = (hbond_parameters*) + calloc( reax->num_atom_types, sizeof(hbond_parameters) ); + reax->fbp[i][j] = (four_body_header**) + calloc( reax->num_atom_types, sizeof(four_body_header*) ); + tor_flag[i][j] = (char**) + calloc( reax->num_atom_types, sizeof(char*) ); + + for (k = 0; k < reax->num_atom_types; k++) + { + reax->fbp[i][j][k] = (four_body_header*) + calloc( reax->num_atom_types, sizeof(four_body_header) ); + tor_flag[i][j][k] = (char*) + calloc( reax->num_atom_types, sizeof(char) ); + } + } + } + + // vdWaals type: 1: Shielded Morse, no inner-wall + // 2: inner wall, no shielding + // 3: inner wall+shielding + reax->gp.vdw_type = 0; + + /* reading single atom parameters */ + /* there are 4 lines of each single atom parameters in ff files. these + parameters later determine some of the pair and triplet parameters using + combination rules. */ + for ( i = 0; i < reax->num_atom_types; i++ ) + { + /* line one */ + fgets( s, MAX_LINE, fp ); + c = Tokenize( s, &tmp ); + + for ( j = 0; j < strlen( tmp[0] ); ++j ) + reax->sbp[i].name[j] = toupper( tmp[0][j] ); + + val = atof(tmp[1]); + reax->sbp[i].r_s = val; + val = atof(tmp[2]); + reax->sbp[i].valency = val; + val = atof(tmp[3]); + reax->sbp[i].mass = val; + val = atof(tmp[4]); + reax->sbp[i].r_vdw = val; + val = atof(tmp[5]); + reax->sbp[i].epsilon = val; + val = atof(tmp[6]); + reax->sbp[i].gamma = val; + val = atof(tmp[7]); + reax->sbp[i].r_pi = val; + val = atof(tmp[8]); + reax->sbp[i].valency_e = val; + reax->sbp[i].nlp_opt = 0.5 * (reax->sbp[i].valency_e - reax->sbp[i].valency); + + /* line two */ + fgets( s, MAX_LINE, fp ); + c = Tokenize( s, &tmp ); + + val = atof(tmp[0]); + reax->sbp[i].alpha = val; + val = atof(tmp[1]); + reax->sbp[i].gamma_w = val; + val = atof(tmp[2]); + reax->sbp[i].valency_boc = val; + val = atof(tmp[3]); + reax->sbp[i].p_ovun5 = val; + val = atof(tmp[4]); + val = atof(tmp[5]); + reax->sbp[i].chi = val; + val = atof(tmp[6]); + reax->sbp[i].eta = 2.0 * val; + /* this is the parameter that is used to determine + which type of atoms participate in h-bonds. + 1 is for H - 2 for O, N, S - 0 for all others.*/ + val = atof(tmp[7]); + reax->sbp[i].p_hbond = (int)(val + 0.1); + //0.1 is to avoid from truncating down! + + /* line 3 */ + fgets( s, MAX_LINE, fp ); + c = Tokenize( s, &tmp ); + + val = atof(tmp[0]); + reax->sbp[i].r_pi_pi = val; + val = atof(tmp[1]); + reax->sbp[i].p_lp2 = val; + val = atof(tmp[2]); + val = atof(tmp[3]); + reax->sbp[i].b_o_131 = val; + val = atof(tmp[4]); + reax->sbp[i].b_o_132 = val; + val = atof(tmp[5]); + reax->sbp[i].b_o_133 = val; + val = atof(tmp[6]); + val = atof(tmp[7]); + + /* line 4 */ + fgets( s, MAX_LINE, fp ); + c = Tokenize( s, &tmp ); + + val = atof(tmp[0]); + reax->sbp[i].p_ovun2 = val; + val = atof(tmp[1]); + reax->sbp[i].p_val3 = val; + val = atof(tmp[2]); + val = atof(tmp[3]); + reax->sbp[i].valency_val = val; + val = atof(tmp[4]); + reax->sbp[i].p_val5 = val; + val = atof(tmp[5]); + reax->sbp[i].rcore2 = val; + val = atof(tmp[6]); + reax->sbp[i].ecore2 = val; + val = atof(tmp[7]); + reax->sbp[i].acore2 = val; + + if ( reax->sbp[i].rcore2 > 0.01 && reax->sbp[i].acore2 > 0.01 ) // Inner-wall + { + if ( reax->sbp[i].gamma_w > 0.5 ) // Shielding vdWaals + { + if ( reax->gp.vdw_type != 0 && reax->gp.vdw_type != 3 ) + fprintf( stderr, "Warning: inconsistent vdWaals-parameters\n" \ + "Force field parameters for element %s\n" \ + "indicate inner wall+shielding, but earlier\n" \ + "atoms indicate different vdWaals-method.\n" \ + "This may cause division-by-zero errors.\n" \ + "Keeping vdWaals-setting for earlier atoms.\n", + reax->sbp[i].name ); + else + { + reax->gp.vdw_type = 3; #if defined(DEBUG) - fprintf( stderr, "vdWaals type for element %s: Shielding+inner-wall", - reax->sbp[i].name ); + fprintf( stderr, "vdWaals type for element %s: Shielding+inner-wall", + reax->sbp[i].name ); #endif - } - } - else { // No shielding vdWaals parameters present - if( reax->gp.vdw_type != 0 && reax->gp.vdw_type != 2 ) - fprintf( stderr, "Warning: inconsistent vdWaals-parameters\n" \ - "Force field parameters for element %s\n" \ - "indicate inner wall without shielding, but earlier\n" \ - "atoms indicate different vdWaals-method.\n" \ - "This may cause division-by-zero errors.\n" \ - "Keeping vdWaals-setting for earlier atoms.\n", - reax->sbp[i].name ); - else{ - reax->gp.vdw_type = 2; + } + } + else // No shielding vdWaals parameters present + { + if ( reax->gp.vdw_type != 0 && reax->gp.vdw_type != 2 ) + fprintf( stderr, "Warning: inconsistent vdWaals-parameters\n" \ + "Force field parameters for element %s\n" \ + "indicate inner wall without shielding, but earlier\n" \ + "atoms indicate different vdWaals-method.\n" \ + "This may cause division-by-zero errors.\n" \ + "Keeping vdWaals-setting for earlier atoms.\n", + reax->sbp[i].name ); + else + { + reax->gp.vdw_type = 2; #if defined(DEBUG) - fprintf( stderr,"vdWaals type for element%s: No Shielding,inner-wall", - reax->sbp[i].name ); + fprintf( stderr, "vdWaals type for element%s: No Shielding,inner-wall", + reax->sbp[i].name ); #endif - } - } - } - else{ // No Inner wall parameters present - if( reax->sbp[i].gamma_w>0.5 ){ // Shielding vdWaals - if( reax->gp.vdw_type != 0 && reax->gp.vdw_type != 1 ) - fprintf( stderr, "Warning: inconsistent vdWaals-parameters\n" \ - "Force field parameters for element %s\n" \ - "indicate shielding without inner wall, but earlier\n" \ - "atoms indicate different vdWaals-method.\n" \ - "This may cause division-by-zero errors.\n" \ - "Keeping vdWaals-setting for earlier atoms.\n", - reax->sbp[i].name ); - else{ - reax->gp.vdw_type = 1; + } + } + } + else // No Inner wall parameters present + { + if ( reax->sbp[i].gamma_w > 0.5 ) // Shielding vdWaals + { + if ( reax->gp.vdw_type != 0 && reax->gp.vdw_type != 1 ) + fprintf( stderr, "Warning: inconsistent vdWaals-parameters\n" \ + "Force field parameters for element %s\n" \ + "indicate shielding without inner wall, but earlier\n" \ + "atoms indicate different vdWaals-method.\n" \ + "This may cause division-by-zero errors.\n" \ + "Keeping vdWaals-setting for earlier atoms.\n", + reax->sbp[i].name ); + else + { + reax->gp.vdw_type = 1; #if defined(DEBUG) - fprintf( stderr,"vdWaals type for element%s: Shielding,no inner-wall", - reax->sbp[i].name ); + fprintf( stderr, "vdWaals type for element%s: Shielding,no inner-wall", + reax->sbp[i].name ); #endif - } - } - else{ - fprintf( stderr, "Error: inconsistent vdWaals-parameters\n"\ - "No shielding or inner-wall set for element %s\n", - reax->sbp[i].name ); - exit( INVALID_INPUT ); - } - } - } - - - /* next line is number of two body combination and some comments */ - fgets(s,MAX_LINE,fp); - c=Tokenize(s,&tmp); - l = atoi(tmp[0]); - - /* a line of comments */ - fgets(s,MAX_LINE,fp); - - for (i=0; i < l; i++) - { - /* line 1 */ - fgets(s,MAX_LINE,fp); - c=Tokenize(s,&tmp); - - j = atoi(tmp[0]) - 1; - k = atoi(tmp[1]) - 1; - - if (j < reax->num_atom_types && k < reax->num_atom_types) - { - - val = atof(tmp[2]); reax->tbp[j][k].De_s = val; - reax->tbp[k][j].De_s = val; - val = atof(tmp[3]); reax->tbp[j][k].De_p = val; - reax->tbp[k][j].De_p = val; - val = atof(tmp[4]); reax->tbp[j][k].De_pp = val; - reax->tbp[k][j].De_pp = val; - val = atof(tmp[5]); reax->tbp[j][k].p_be1 = val; - reax->tbp[k][j].p_be1 = val; - val = atof(tmp[6]); reax->tbp[j][k].p_bo5 = val; - reax->tbp[k][j].p_bo5 = val; - val = atof(tmp[7]); reax->tbp[j][k].v13cor = val; - reax->tbp[k][j].v13cor = val; - - val = atof(tmp[8]); reax->tbp[j][k].p_bo6 = val; - reax->tbp[k][j].p_bo6 = val; - val = atof(tmp[9]); reax->tbp[j][k].p_ovun1 = val; - reax->tbp[k][j].p_ovun1 = val; - - /* line 2 */ - fgets(s,MAX_LINE,fp); - c=Tokenize(s,&tmp); - - val = atof(tmp[0]); reax->tbp[j][k].p_be2 = val; - reax->tbp[k][j].p_be2 = val; - val = atof(tmp[1]); reax->tbp[j][k].p_bo3 = val; - reax->tbp[k][j].p_bo3 = val; - val = atof(tmp[2]); reax->tbp[j][k].p_bo4 = val; - reax->tbp[k][j].p_bo4 = val; - val = atof(tmp[3]); - - val = atof(tmp[4]); reax->tbp[j][k].p_bo1 = val; - reax->tbp[k][j].p_bo1 = val; - val = atof(tmp[5]); reax->tbp[j][k].p_bo2 = val; - reax->tbp[k][j].p_bo2 = val; - val = atof(tmp[6]); reax->tbp[j][k].ovc = val; - reax->tbp[k][j].ovc = val; - - val = atof(tmp[7]); - } + } + } + else + { + fprintf( stderr, "Error: inconsistent vdWaals-parameters\n"\ + "No shielding or inner-wall set for element %s\n", + reax->sbp[i].name ); + exit( INVALID_INPUT ); + } + } } - /* calculating combination rules and filling up remaining fields. */ - - for (i=0; i < reax->num_atom_types; i++) - for (j=i; j < reax->num_atom_types; j++) - { - reax->tbp[i][j].r_s = 0.5 * - (reax->sbp[i].r_s + reax->sbp[j].r_s); - reax->tbp[j][i].r_s = 0.5 * - (reax->sbp[j].r_s + reax->sbp[i].r_s); - - reax->tbp[i][j].r_p = 0.5 * - (reax->sbp[i].r_pi + reax->sbp[j].r_pi); - reax->tbp[j][i].r_p = 0.5 * - (reax->sbp[j].r_pi + reax->sbp[i].r_pi); - - reax->tbp[i][j].r_pp = 0.5 * - (reax->sbp[i].r_pi_pi + reax->sbp[j].r_pi_pi); - reax->tbp[j][i].r_pp = 0.5 * - (reax->sbp[j].r_pi_pi + reax->sbp[i].r_pi_pi); - - - reax->tbp[i][j].p_boc3 = - sqrt(reax->sbp[i].b_o_132 * - reax->sbp[j].b_o_132); - reax->tbp[j][i].p_boc3 = - sqrt(reax->sbp[j].b_o_132 * - reax->sbp[i].b_o_132); - - reax->tbp[i][j].p_boc4 = - sqrt(reax->sbp[i].b_o_131 * - reax->sbp[j].b_o_131); - reax->tbp[j][i].p_boc4 = - sqrt(reax->sbp[j].b_o_131 * - reax->sbp[i].b_o_131); - - reax->tbp[i][j].p_boc5 = - sqrt(reax->sbp[i].b_o_133 * - reax->sbp[j].b_o_133); - reax->tbp[j][i].p_boc5 = - sqrt(reax->sbp[j].b_o_133 * - reax->sbp[i].b_o_133); - - - reax->tbp[i][j].D = - sqrt(reax->sbp[i].epsilon * - reax->sbp[j].epsilon); - - reax->tbp[j][i].D = - sqrt(reax->sbp[j].epsilon * - reax->sbp[i].epsilon); - - reax->tbp[i][j].alpha = - sqrt(reax->sbp[i].alpha * - reax->sbp[j].alpha); - - reax->tbp[j][i].alpha = - sqrt(reax->sbp[j].alpha * - reax->sbp[i].alpha); - - reax->tbp[i][j].r_vdW = - 2.0 * sqrt(reax->sbp[i].r_vdw * reax->sbp[j].r_vdw); - - reax->tbp[j][i].r_vdW = - 2.0 * sqrt(reax->sbp[j].r_vdw * reax->sbp[i].r_vdw); - - reax->tbp[i][j].gamma_w = - sqrt(reax->sbp[i].gamma_w * - reax->sbp[j].gamma_w); - - reax->tbp[j][i].gamma_w = - sqrt(reax->sbp[j].gamma_w * - reax->sbp[i].gamma_w); - - reax->tbp[i][j].gamma = - POW(reax->sbp[i].gamma * - reax->sbp[j].gamma,-1.5); - - reax->tbp[j][i].gamma = - POW(reax->sbp[j].gamma * - reax->sbp[i].gamma,-1.5); - - } - - - /* next line is number of 2-body offdiagonal combinations and some comments */ - /* these are two body offdiagonal terms that are different from the - combination rules defined above */ - fgets(s,MAX_LINE,fp); - c=Tokenize(s,&tmp); - l = atoi(tmp[0]); - - for (i=0; i < l; i++) - { - fgets(s,MAX_LINE,fp); - c=Tokenize(s,&tmp); - - j = atoi(tmp[0]) - 1; - k = atoi(tmp[1]) - 1; - - if (j < reax->num_atom_types && k < reax->num_atom_types) - { - val = atof(tmp[2]); - if (val > 0.0) - { - reax->tbp[j][k].D = val; - reax->tbp[k][j].D = val; - } - - val = atof(tmp[3]); - if (val > 0.0) - { - reax->tbp[j][k].r_vdW = 2 * val; - reax->tbp[k][j].r_vdW = 2 * val; - } - - val = atof(tmp[4]); - if (val > 0.0) - { - reax->tbp[j][k].alpha = val; - reax->tbp[k][j].alpha = val; - } - - val = atof(tmp[5]); - 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) - { - reax->tbp[j][k].r_p = val; - reax->tbp[k][j].r_p = val; - } - - val = atof(tmp[7]); - if (val > 0.0) - { - reax->tbp[j][k].r_pp = val; - reax->tbp[k][j].r_pp = val; - } - } - } - - - /* 3-body parameters - - supports multi-well potentials (upto MAX_3BODY_PARAM in mytypes.h) */ - /* clear entries first */ - for( i = 0; i < reax->num_atom_types; ++i ) - for( j = 0; j < reax->num_atom_types; ++j ) - for( k = 0; k < reax->num_atom_types; ++k ) - reax->thbp[i][j][k].cnt = 0; - - /* next line is number of 3-body params and some comments */ - fgets( s, MAX_LINE, fp ); - c = Tokenize( s, &tmp ); - l = atoi( tmp[0] ); - - for( i = 0; i < l; i++ ) - { - fgets(s,MAX_LINE,fp); - c=Tokenize(s,&tmp); - - j = atoi(tmp[0]) - 1; - 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) - { - cnt = reax->thbp[j][k][m].cnt; - reax->thbp[j][k][m].cnt++; - reax->thbp[m][k][j].cnt++; - - val = atof(tmp[3]); - reax->thbp[j][k][m].prm[cnt].theta_00 = val; - reax->thbp[m][k][j].prm[cnt].theta_00 = val; - - val = atof(tmp[4]); - reax->thbp[j][k][m].prm[cnt].p_val1 = val; - reax->thbp[m][k][j].prm[cnt].p_val1 = val; - - val = atof(tmp[5]); - reax->thbp[j][k][m].prm[cnt].p_val2 = val; - reax->thbp[m][k][j].prm[cnt].p_val2 = val; - - val = atof(tmp[6]); - reax->thbp[j][k][m].prm[cnt].p_coa1 = val; - reax->thbp[m][k][j].prm[cnt].p_coa1 = val; - - val = atof(tmp[7]); - reax->thbp[j][k][m].prm[cnt].p_val7 = val; - reax->thbp[m][k][j].prm[cnt].p_val7 = val; - - val = atof(tmp[8]); - reax->thbp[j][k][m].prm[cnt].p_pen1 = val; - reax->thbp[m][k][j].prm[cnt].p_pen1 = val; - - val = atof(tmp[9]); - reax->thbp[j][k][m].prm[cnt].p_val4 = val; - reax->thbp[m][k][j].prm[cnt].p_val4 = val; - } - } + /* next line is number of two body combination and some comments */ + fgets(s, MAX_LINE, fp); + c = Tokenize(s, &tmp); + l = atoi(tmp[0]); - /* 4-body parameters are entered in compact form. i.e. 0-X-Y-0 - correspond to any type of pair of atoms in 1 and 4 - position. However, explicit X-Y-Z-W takes precedence over the - default description. - supports multi-well potentials (upto MAX_4BODY_PARAM in mytypes.h) - IMPORTANT: for now, directions on how to read multi-entries from ffield - is not clear */ - - /* clear all entries first */ - for( i = 0; i < reax->num_atom_types; ++i ) - for( j = 0; j < reax->num_atom_types; ++j ) - for( k = 0; k < reax->num_atom_types; ++k ) - for( m = 0; m < reax->num_atom_types; ++m ) - { - reax->fbp[i][j][k][m].cnt = 0; - tor_flag[i][j][k][m] = 0; - } - - /* next line is number of 4-body params and some comments */ - fgets( s, MAX_LINE, fp ); - c = Tokenize( s, &tmp ); - l = atoi( tmp[0] ); - - for( i = 0; i < l; i++ ) + /* a line of comments */ + fgets(s, MAX_LINE, fp); + + for (i = 0; i < l; i++) { - fgets( s, MAX_LINE, fp ); - c = Tokenize( s, &tmp ); - - j = atoi(tmp[0]) - 1; - k = atoi(tmp[1]) - 1; - m = atoi(tmp[2]) - 1; - n = atoi(tmp[3]) - 1; - - if (j >= 0 && n >= 0) // this means the entry is not in compact form - { - 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 */ - tor_flag[j][k][m][n] = 1; - tor_flag[n][m][k][j] = 1; - - reax->fbp[j][k][m][n].cnt = 1; - reax->fbp[n][m][k][j].cnt = 1; - /* cnt = reax->fbp[j][k][m][n].cnt; - reax->fbp[j][k][m][n].cnt++; - reax->fbp[n][m][k][j].cnt++; */ - - val = atof(tmp[4]); - reax->fbp[j][k][m][n].prm[0].V1 = val; - reax->fbp[n][m][k][j].prm[0].V1 = val; - - val = atof(tmp[5]); - reax->fbp[j][k][m][n].prm[0].V2 = val; - reax->fbp[n][m][k][j].prm[0].V2 = val; - - val = atof(tmp[6]); - reax->fbp[j][k][m][n].prm[0].V3 = val; - reax->fbp[n][m][k][j].prm[0].V3 = val; - - val = atof(tmp[7]); - reax->fbp[j][k][m][n].prm[0].p_tor1 = val; - reax->fbp[n][m][k][j].prm[0].p_tor1 = val; - - val = atof(tmp[8]); - reax->fbp[j][k][m][n].prm[0].p_cot1 = val; - reax->fbp[n][m][k][j].prm[0].p_cot1 = val; - } - } - else /* This means the entry is of the form 0-X-Y-0 */ - { - if( k < reax->num_atom_types && m < reax->num_atom_types ) - for( p = 0; p < reax->num_atom_types; p++ ) - for( o = 0; o < reax->num_atom_types; o++ ) - { - reax->fbp[p][k][m][o].cnt = 1; - reax->fbp[o][m][k][p].cnt = 1; - /* cnt = reax->fbp[p][k][m][o].cnt; - reax->fbp[p][k][m][o].cnt++; - reax->fbp[o][m][k][p].cnt++; */ - - 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]); - reax->fbp[p][k][m][o].prm[0].V3 = atof(tmp[6]); - reax->fbp[p][k][m][o].prm[0].p_tor1 = atof(tmp[7]); - reax->fbp[p][k][m][o].prm[0].p_cot1 = atof(tmp[8]); - } - - 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]); - reax->fbp[o][m][k][p].prm[0].V3 = atof(tmp[6]); - reax->fbp[o][m][k][p].prm[0].p_tor1 = atof(tmp[7]); - reax->fbp[o][m][k][p].prm[0].p_cot1 = atof(tmp[8]); - } - } - } - } + /* line 1 */ + fgets(s, MAX_LINE, fp); + c = Tokenize(s, &tmp); + + j = atoi(tmp[0]) - 1; + k = atoi(tmp[1]) - 1; + + if (j < reax->num_atom_types && k < reax->num_atom_types) + { + + val = atof(tmp[2]); + reax->tbp[j][k].De_s = val; + reax->tbp[k][j].De_s = val; + val = atof(tmp[3]); + reax->tbp[j][k].De_p = val; + reax->tbp[k][j].De_p = val; + val = atof(tmp[4]); + reax->tbp[j][k].De_pp = val; + reax->tbp[k][j].De_pp = val; + val = atof(tmp[5]); + reax->tbp[j][k].p_be1 = val; + reax->tbp[k][j].p_be1 = val; + val = atof(tmp[6]); + reax->tbp[j][k].p_bo5 = val; + reax->tbp[k][j].p_bo5 = val; + val = atof(tmp[7]); + reax->tbp[j][k].v13cor = val; + reax->tbp[k][j].v13cor = val; + + val = atof(tmp[8]); + reax->tbp[j][k].p_bo6 = val; + reax->tbp[k][j].p_bo6 = val; + val = atof(tmp[9]); + reax->tbp[j][k].p_ovun1 = val; + reax->tbp[k][j].p_ovun1 = val; + + /* line 2 */ + fgets(s, MAX_LINE, fp); + c = Tokenize(s, &tmp); + + val = atof(tmp[0]); + reax->tbp[j][k].p_be2 = val; + reax->tbp[k][j].p_be2 = val; + val = atof(tmp[1]); + reax->tbp[j][k].p_bo3 = val; + reax->tbp[k][j].p_bo3 = val; + val = atof(tmp[2]); + reax->tbp[j][k].p_bo4 = val; + reax->tbp[k][j].p_bo4 = val; + val = atof(tmp[3]); + + val = atof(tmp[4]); + reax->tbp[j][k].p_bo1 = val; + reax->tbp[k][j].p_bo1 = val; + val = atof(tmp[5]); + reax->tbp[j][k].p_bo2 = val; + reax->tbp[k][j].p_bo2 = val; + val = atof(tmp[6]); + reax->tbp[j][k].ovc = val; + reax->tbp[k][j].ovc = val; + + val = atof(tmp[7]); + } + } + + /* calculating combination rules and filling up remaining fields. */ + + for (i = 0; i < reax->num_atom_types; i++) + for (j = i; j < reax->num_atom_types; j++) + { + reax->tbp[i][j].r_s = 0.5 * + (reax->sbp[i].r_s + reax->sbp[j].r_s); + reax->tbp[j][i].r_s = 0.5 * + (reax->sbp[j].r_s + reax->sbp[i].r_s); + + reax->tbp[i][j].r_p = 0.5 * + (reax->sbp[i].r_pi + reax->sbp[j].r_pi); + reax->tbp[j][i].r_p = 0.5 * + (reax->sbp[j].r_pi + reax->sbp[i].r_pi); + + reax->tbp[i][j].r_pp = 0.5 * + (reax->sbp[i].r_pi_pi + reax->sbp[j].r_pi_pi); + reax->tbp[j][i].r_pp = 0.5 * + (reax->sbp[j].r_pi_pi + reax->sbp[i].r_pi_pi); + + + reax->tbp[i][j].p_boc3 = + sqrt(reax->sbp[i].b_o_132 * + reax->sbp[j].b_o_132); + reax->tbp[j][i].p_boc3 = + sqrt(reax->sbp[j].b_o_132 * + reax->sbp[i].b_o_132); + + reax->tbp[i][j].p_boc4 = + sqrt(reax->sbp[i].b_o_131 * + reax->sbp[j].b_o_131); + reax->tbp[j][i].p_boc4 = + sqrt(reax->sbp[j].b_o_131 * + reax->sbp[i].b_o_131); + + reax->tbp[i][j].p_boc5 = + sqrt(reax->sbp[i].b_o_133 * + reax->sbp[j].b_o_133); + reax->tbp[j][i].p_boc5 = + sqrt(reax->sbp[j].b_o_133 * + reax->sbp[i].b_o_133); + + + reax->tbp[i][j].D = + sqrt(reax->sbp[i].epsilon * + reax->sbp[j].epsilon); + + reax->tbp[j][i].D = + sqrt(reax->sbp[j].epsilon * + reax->sbp[i].epsilon); + + reax->tbp[i][j].alpha = + sqrt(reax->sbp[i].alpha * + reax->sbp[j].alpha); + + reax->tbp[j][i].alpha = + sqrt(reax->sbp[j].alpha * + reax->sbp[i].alpha); + + reax->tbp[i][j].r_vdW = + 2.0 * sqrt(reax->sbp[i].r_vdw * reax->sbp[j].r_vdw); + + reax->tbp[j][i].r_vdW = + 2.0 * sqrt(reax->sbp[j].r_vdw * reax->sbp[i].r_vdw); + + reax->tbp[i][j].gamma_w = + sqrt(reax->sbp[i].gamma_w * + reax->sbp[j].gamma_w); + + reax->tbp[j][i].gamma_w = + sqrt(reax->sbp[j].gamma_w * + reax->sbp[i].gamma_w); + + reax->tbp[i][j].gamma = + POW(reax->sbp[i].gamma * + reax->sbp[j].gamma, -1.5); + + reax->tbp[j][i].gamma = + POW(reax->sbp[j].gamma * + reax->sbp[i].gamma, -1.5); + + } + + + /* next line is number of 2-body offdiagonal combinations and some comments */ + /* these are two body offdiagonal terms that are different from the + combination rules defined above */ + fgets(s, MAX_LINE, fp); + c = Tokenize(s, &tmp); + l = atoi(tmp[0]); + for (i = 0; i < l; i++) + { + fgets(s, MAX_LINE, fp); + c = Tokenize(s, &tmp); + + j = atoi(tmp[0]) - 1; + k = atoi(tmp[1]) - 1; + + if (j < reax->num_atom_types && k < reax->num_atom_types) + { + val = atof(tmp[2]); + if (val > 0.0) + { + reax->tbp[j][k].D = val; + reax->tbp[k][j].D = val; + } + + val = atof(tmp[3]); + if (val > 0.0) + { + reax->tbp[j][k].r_vdW = 2 * val; + reax->tbp[k][j].r_vdW = 2 * val; + } + + val = atof(tmp[4]); + if (val > 0.0) + { + reax->tbp[j][k].alpha = val; + reax->tbp[k][j].alpha = val; + } + + val = atof(tmp[5]); + 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) + { + reax->tbp[j][k].r_p = val; + reax->tbp[k][j].r_p = val; + } + + val = atof(tmp[7]); + if (val > 0.0) + { + reax->tbp[j][k].r_pp = val; + reax->tbp[k][j].r_pp = val; + } + } + } + + + /* 3-body parameters - + supports multi-well potentials (upto MAX_3BODY_PARAM in mytypes.h) */ + /* clear entries first */ + for ( i = 0; i < reax->num_atom_types; ++i ) + for ( j = 0; j < reax->num_atom_types; ++j ) + for ( k = 0; k < reax->num_atom_types; ++k ) + reax->thbp[i][j][k].cnt = 0; + + /* next line is number of 3-body params and some comments */ + fgets( s, MAX_LINE, fp ); + c = Tokenize( s, &tmp ); + l = atoi( tmp[0] ); + for ( i = 0; i < l; i++ ) + { + fgets(s, MAX_LINE, fp); + c = Tokenize(s, &tmp); + + j = atoi(tmp[0]) - 1; + 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) + { + cnt = reax->thbp[j][k][m].cnt; + reax->thbp[j][k][m].cnt++; + reax->thbp[m][k][j].cnt++; + + val = atof(tmp[3]); + reax->thbp[j][k][m].prm[cnt].theta_00 = val; + reax->thbp[m][k][j].prm[cnt].theta_00 = val; + + val = atof(tmp[4]); + reax->thbp[j][k][m].prm[cnt].p_val1 = val; + reax->thbp[m][k][j].prm[cnt].p_val1 = val; + + val = atof(tmp[5]); + reax->thbp[j][k][m].prm[cnt].p_val2 = val; + reax->thbp[m][k][j].prm[cnt].p_val2 = val; + + val = atof(tmp[6]); + reax->thbp[j][k][m].prm[cnt].p_coa1 = val; + reax->thbp[m][k][j].prm[cnt].p_coa1 = val; + + val = atof(tmp[7]); + reax->thbp[j][k][m].prm[cnt].p_val7 = val; + reax->thbp[m][k][j].prm[cnt].p_val7 = val; + + val = atof(tmp[8]); + reax->thbp[j][k][m].prm[cnt].p_pen1 = val; + reax->thbp[m][k][j].prm[cnt].p_pen1 = val; + + val = atof(tmp[9]); + reax->thbp[j][k][m].prm[cnt].p_val4 = val; + reax->thbp[m][k][j].prm[cnt].p_val4 = val; + } + } + + + /* 4-body parameters are entered in compact form. i.e. 0-X-Y-0 + correspond to any type of pair of atoms in 1 and 4 + position. However, explicit X-Y-Z-W takes precedence over the + default description. + supports multi-well potentials (upto MAX_4BODY_PARAM in mytypes.h) + IMPORTANT: for now, directions on how to read multi-entries from ffield + is not clear */ + + /* clear all entries first */ + for ( i = 0; i < reax->num_atom_types; ++i ) + for ( j = 0; j < reax->num_atom_types; ++j ) + for ( k = 0; k < reax->num_atom_types; ++k ) + for ( m = 0; m < reax->num_atom_types; ++m ) + { + reax->fbp[i][j][k][m].cnt = 0; + tor_flag[i][j][k][m] = 0; + } + + /* next line is number of 4-body params and some comments */ + fgets( s, MAX_LINE, fp ); + c = Tokenize( s, &tmp ); + l = atoi( tmp[0] ); - /* next line is number of hydrogen bond params and some comments */ - fgets( s, MAX_LINE, fp ); - c = Tokenize( s, &tmp ); - l = atoi( tmp[0] ); + for ( i = 0; i < l; i++ ) + { + fgets( s, MAX_LINE, fp ); + c = Tokenize( s, &tmp ); + + j = atoi(tmp[0]) - 1; + k = atoi(tmp[1]) - 1; + m = atoi(tmp[2]) - 1; + n = atoi(tmp[3]) - 1; + + if (j >= 0 && n >= 0) // this means the entry is not in compact form + { + 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 */ + tor_flag[j][k][m][n] = 1; + tor_flag[n][m][k][j] = 1; + + reax->fbp[j][k][m][n].cnt = 1; + reax->fbp[n][m][k][j].cnt = 1; + /* cnt = reax->fbp[j][k][m][n].cnt; + reax->fbp[j][k][m][n].cnt++; + reax->fbp[n][m][k][j].cnt++; */ + + val = atof(tmp[4]); + reax->fbp[j][k][m][n].prm[0].V1 = val; + reax->fbp[n][m][k][j].prm[0].V1 = val; + + val = atof(tmp[5]); + reax->fbp[j][k][m][n].prm[0].V2 = val; + reax->fbp[n][m][k][j].prm[0].V2 = val; + + val = atof(tmp[6]); + reax->fbp[j][k][m][n].prm[0].V3 = val; + reax->fbp[n][m][k][j].prm[0].V3 = val; + + val = atof(tmp[7]); + reax->fbp[j][k][m][n].prm[0].p_tor1 = val; + reax->fbp[n][m][k][j].prm[0].p_tor1 = val; + + val = atof(tmp[8]); + reax->fbp[j][k][m][n].prm[0].p_cot1 = val; + reax->fbp[n][m][k][j].prm[0].p_cot1 = val; + } + } + else /* This means the entry is of the form 0-X-Y-0 */ + { + if ( k < reax->num_atom_types && m < reax->num_atom_types ) + for ( p = 0; p < reax->num_atom_types; p++ ) + for ( o = 0; o < reax->num_atom_types; o++ ) + { + reax->fbp[p][k][m][o].cnt = 1; + reax->fbp[o][m][k][p].cnt = 1; + /* cnt = reax->fbp[p][k][m][o].cnt; + reax->fbp[p][k][m][o].cnt++; + reax->fbp[o][m][k][p].cnt++; */ + + 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]); + reax->fbp[p][k][m][o].prm[0].V3 = atof(tmp[6]); + reax->fbp[p][k][m][o].prm[0].p_tor1 = atof(tmp[7]); + reax->fbp[p][k][m][o].prm[0].p_cot1 = atof(tmp[8]); + } + + 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]); + reax->fbp[o][m][k][p].prm[0].V3 = atof(tmp[6]); + reax->fbp[o][m][k][p].prm[0].p_tor1 = atof(tmp[7]); + reax->fbp[o][m][k][p].prm[0].p_cot1 = atof(tmp[8]); + } + } + } + } + + + + /* next line is number of hydrogen bond params and some comments */ + fgets( s, MAX_LINE, fp ); + c = Tokenize( s, &tmp ); + l = atoi( tmp[0] ); - for( i = 0; i < l; i++ ) + for ( i = 0; i < l; i++ ) { - fgets( s, MAX_LINE, fp ); - c = Tokenize( s, &tmp ); - - j = atoi(tmp[0]) - 1; - k = atoi(tmp[1]) - 1; - m = atoi(tmp[2]) - 1; + fgets( s, MAX_LINE, fp ); + c = Tokenize( s, &tmp ); + + j = atoi(tmp[0]) - 1; + k = atoi(tmp[1]) - 1; + m = atoi(tmp[2]) - 1; - if (j < reax->num_atom_types && m < reax->num_atom_types) - { - val = atof(tmp[3]); - reax->hbp[j][k][m].r0_hb = val; + if (j < reax->num_atom_types && m < reax->num_atom_types) + { + val = atof(tmp[3]); + reax->hbp[j][k][m].r0_hb = val; - val = atof(tmp[4]); - reax->hbp[j][k][m].p_hb1 = val; + val = atof(tmp[4]); + reax->hbp[j][k][m].p_hb1 = val; - val = atof(tmp[5]); - reax->hbp[j][k][m].p_hb2 = val; + val = atof(tmp[5]); + reax->hbp[j][k][m].p_hb2 = val; - val = atof(tmp[6]); - reax->hbp[j][k][m].p_hb3 = val; + val = atof(tmp[6]); + reax->hbp[j][k][m].p_hb3 = val; - } + } } - - /* deallocate helper storage */ - for( i = 0; i < MAX_TOKENS; i++ ) - free( tmp[i] ); - free( tmp ); - free( s ); + + /* deallocate helper storage */ + for ( i = 0; i < MAX_TOKENS; i++ ) + free( tmp[i] ); + free( tmp ); + free( s ); - /* deallocate tor_flag */ - for( i = 0; i < reax->num_atom_types; i++ ) + /* deallocate tor_flag */ + for ( i = 0; i < reax->num_atom_types; i++ ) { - for( j = 0; j < reax->num_atom_types; j++ ) - { - for( k = 0; k < reax->num_atom_types; k++ ) - free( tor_flag[i][j][k] ); - - free( tor_flag[i][j] ); - } - - free( tor_flag[i] ); + for ( j = 0; j < reax->num_atom_types; j++ ) + { + for ( k = 0; k < reax->num_atom_types; k++ ) + free( tor_flag[i][j][k] ); + + free( tor_flag[i][j] ); + } + + free( tor_flag[i] ); } #if defined(DEBUG_FOCUS) - fprintf( stderr, "force field read\n" ); + fprintf( stderr, "force field read\n" ); #endif - return 0; + return 0; } char Read_Control_File( FILE* fp, reax_system *system, control_params* control, - output_controls *out_control ) + output_controls *out_control ) { - char *s, **tmp; - int c,i; - real val; - int ival; - - /* assign default values */ - strcpy( control->sim_name, "default.sim" ); - - control->restart = 0; - out_control->restart_format = 1; - out_control->restart_freq = 0; - strcpy( control->restart_from, "default.res" ); - out_control->restart_freq = 0; - control->random_vel = 0; - - control->reposition_atoms = 0; - - control->ensemble = 0; - control->nsteps = 0; - control->dt = 0.25; - - control->geo_format = 1; - control->restrict_bonds = 0; - - control->periodic_boundaries = 1; - control->periodic_images[0] = 0; - control->periodic_images[1] = 0; - control->periodic_images[2] = 0; - - control->reneighbor = 1; - control->vlist_cut = 0; - control->nbr_cut = 4.; - control->r_cut = 10; - control->max_far_nbrs = 1000; - control->bo_cut = 0.01; - control->thb_cut = 0.001; - control->hb_cut = 7.50; - - control->q_err = 0.000001; - control->tabulate = 0; - control->refactor = 100; - control->droptol = 0.01; - - control->T_init = 0.; - control->T_final = 300.; - control->Tau_T = 1.0; - control->T_mode = 0.; - control->T_rate = 1.; - control->T_freq = 1.; - - control->P[0] = 0.000101325; - control->P[1] = 0.000101325; - control->P[2] = 0.000101325; - control->Tau_P[0] = 500.0; - control->Tau_P[1] = 500.0; - control->Tau_P[2] = 500.0; - control->Tau_PT = 500.0; - control->compressibility = 1.0; - control->press_mode = 0; - - control->remove_CoM_vel = 25; - - out_control->debug_level = 0; - out_control->energy_update_freq = 10; - - out_control->write_steps = 100; - out_control->traj_compress = 0; - out_control->write = fprintf; - out_control->traj_format = 0; - out_control->write_header = - (int (*)( reax_system*, control_params*, - static_storage*, void* )) Write_Custom_Header; - out_control->append_traj_frame = - (int (*)( reax_system*, control_params*, simulation_data*, - static_storage*, list **, void* )) Append_Custom_Frame; - - strcpy( out_control->traj_title, "default_title" ); - out_control->atom_format = 0; - out_control->bond_info = 0; - out_control->angle_info = 0; - - control->molec_anal = 0; - control->freq_molec_anal = 0; - control->bg_cut = 0.3; - control->num_ignored = 0; - memset( control->ignore, 0, sizeof(int)*MAX_ATOM_TYPES ); - - control->dipole_anal = 0; - control->freq_dipole_anal = 0; - - control->diffusion_coef = 0; - control->freq_diffusion_coef = 0; - control->restrict_type = 0; - - /* memory allocations */ - s = (char*) malloc(sizeof(char)*MAX_LINE); - tmp = (char**) malloc(sizeof(char*)*MAX_TOKENS); - for (i=0; i < MAX_TOKENS; i++) - tmp[i] = (char*) malloc(sizeof(char)*MAX_LINE); - - /* read control parameters file */ + char *s, **tmp; + int c, i; + real val; + int ival; + + /* assign default values */ + strcpy( control->sim_name, "default.sim" ); + + control->restart = 0; + out_control->restart_format = 1; + out_control->restart_freq = 0; + strcpy( control->restart_from, "default.res" ); + out_control->restart_freq = 0; + control->random_vel = 0; + + control->reposition_atoms = 0; + + control->ensemble = 0; + control->nsteps = 0; + control->dt = 0.25; + + control->geo_format = 1; + control->restrict_bonds = 0; + + control->periodic_boundaries = 1; + control->periodic_images[0] = 0; + control->periodic_images[1] = 0; + control->periodic_images[2] = 0; + + control->reneighbor = 1; + control->vlist_cut = 0; + control->nbr_cut = 4.; + control->r_cut = 10; + control->max_far_nbrs = 1000; + control->bo_cut = 0.01; + control->thb_cut = 0.001; + control->hb_cut = 7.50; + + control->q_err = 0.000001; + control->tabulate = 0; + control->refactor = 100; + control->droptol = 0.01; + + control->T_init = 0.; + control->T_final = 300.; + control->Tau_T = 1.0; + control->T_mode = 0.; + control->T_rate = 1.; + control->T_freq = 1.; + + control->P[0] = 0.000101325; + control->P[1] = 0.000101325; + control->P[2] = 0.000101325; + control->Tau_P[0] = 500.0; + control->Tau_P[1] = 500.0; + control->Tau_P[2] = 500.0; + control->Tau_PT = 500.0; + control->compressibility = 1.0; + control->press_mode = 0; + + control->remove_CoM_vel = 25; + + out_control->debug_level = 0; + out_control->energy_update_freq = 10; + + out_control->write_steps = 100; + out_control->traj_compress = 0; + out_control->write = fprintf; + out_control->traj_format = 0; + out_control->write_header = + (int (*)( reax_system*, control_params*, + static_storage*, void* )) Write_Custom_Header; + out_control->append_traj_frame = + (int (*)( reax_system*, control_params*, simulation_data*, + static_storage*, list **, void* )) Append_Custom_Frame; + + strcpy( out_control->traj_title, "default_title" ); + out_control->atom_format = 0; + out_control->bond_info = 0; + out_control->angle_info = 0; + + control->molec_anal = 0; + control->freq_molec_anal = 0; + control->bg_cut = 0.3; + control->num_ignored = 0; + memset( control->ignore, 0, sizeof(int)*MAX_ATOM_TYPES ); + + control->dipole_anal = 0; + control->freq_dipole_anal = 0; + + control->diffusion_coef = 0; + control->freq_diffusion_coef = 0; + control->restrict_type = 0; + + /* memory allocations */ + s = (char*) malloc(sizeof(char) * MAX_LINE); + tmp = (char**) malloc(sizeof(char*)*MAX_TOKENS); + for (i = 0; i < MAX_TOKENS; i++) + tmp[i] = (char*) malloc(sizeof(char) * MAX_LINE); + + /* read control parameters file */ // while (!feof(fp)) { - while(fgets(s,MAX_LINE,fp)) - { - c=Tokenize(s,&tmp); - - if( strcmp(tmp[0], "simulation_name") == 0 ) { - strcpy( control->sim_name, tmp[1] ); - } - //else if( strcmp(tmp[0], "restart") == 0 ) { - // ival = atoi(tmp[1]); - // control->restart = ival; - //} - else if( strcmp(tmp[0], "restart_format") == 0 ) { - ival = atoi(tmp[1]); - out_control->restart_format = ival; - } - else if( strcmp(tmp[0], "restart_freq") == 0 ) { - ival = atoi(tmp[1]); - out_control->restart_freq = ival; - } - else if( strcmp(tmp[0], "random_vel") == 0 ) { - ival = atoi(tmp[1]); - control->random_vel = ival; - } - else if( strcmp(tmp[0], "reposition_atoms") == 0 ) { - ival = atoi(tmp[1]); - control->reposition_atoms = ival; - } - else if( strcmp(tmp[0], "ensemble_type") == 0 ) { - ival = atoi(tmp[1]); - control->ensemble = ival; - } - else if( strcmp(tmp[0], "nsteps") == 0 ) { - ival = atoi(tmp[1]); - control->nsteps = ival; - } - else if( strcmp(tmp[0], "dt") == 0 ) { - val = atof(tmp[1]); - control->dt = val * 1.e-3; // convert dt from fs to ps! - } - else if( strcmp(tmp[0], "periodic_boundaries") == 0 ) { - ival = atoi( tmp[1] ); - control->periodic_boundaries = ival; - } - else if( strcmp(tmp[0], "periodic_images") == 0 ) { - ival = atoi(tmp[1]); - control->periodic_images[0] = ival; - ival = atoi(tmp[2]); - control->periodic_images[1] = ival; - ival = atoi(tmp[3]); - control->periodic_images[2] = ival; - } - else if( strcmp(tmp[0], "geo_format") == 0 ) { - ival = atoi( tmp[1] ); - control->geo_format = ival; - } - else if( strcmp(tmp[0], "restrict_bonds") == 0 ) { - ival = atoi( tmp[1] ); - control->restrict_bonds = ival; - } - else if( strcmp(tmp[0], "tabulate_long_range") == 0 ) { - ival = atoi( tmp[1] ); - control->tabulate = ival; - } - else if( strcmp(tmp[0], "reneighbor") == 0 ) { - ival = atoi( tmp[1] ); - control->reneighbor = ival; - } - else if( strcmp(tmp[0], "vlist_buffer") == 0 ) { - val = atof(tmp[1]); - control->vlist_cut= val; - } - else if( strcmp(tmp[0], "nbrhood_cutoff") == 0 ) { - val = atof(tmp[1]); - control->nbr_cut = val; - } - else if( strcmp(tmp[0], "thb_cutoff") == 0 ) { - val = atof(tmp[1]); - control->thb_cut = val; - } - else if( strcmp(tmp[0], "hbond_cutoff") == 0 ) { - val = atof( tmp[1] ); - control->hb_cut = val; - } - else if( strcmp(tmp[0], "q_err") == 0 ) { - val = atof( tmp[1] ); - control->q_err = val; - } - else if( strcmp(tmp[0], "ilu_refactor") == 0 ) { - ival = atoi( tmp[1] ); - control->refactor = ival; - } - else if( strcmp(tmp[0], "ilu_droptol") == 0 ) { - val = atof( tmp[1] ); - control->droptol = val; - } - else if( strcmp(tmp[0], "temp_init") == 0 ) { - val = atof(tmp[1]); - control->T_init = val; - - if( control->T_init < 0.001 ) - control->T_init = 0.001; - } - else if( strcmp(tmp[0], "temp_final") == 0 ) { - val = atof(tmp[1]); - control->T_final = val; - - if( control->T_final < 0.1 ) - control->T_final = 0.1; - } - else if( strcmp(tmp[0], "t_mass") == 0 ) { - val = atof(tmp[1]); - control->Tau_T = val * 1.e-3; // convert t_mass from fs to ps - } - else if( strcmp(tmp[0], "t_mode") == 0 ) { - ival = atoi(tmp[1]); - control->T_mode = ival; - } - else if( strcmp(tmp[0], "t_rate") == 0 ) { - val = atof(tmp[1]); - control->T_rate = val; - } - else if( strcmp(tmp[0], "t_freq") == 0 ) { - val = atof(tmp[1]); - control->T_freq = val; - } - else if( strcmp(tmp[0], "pressure") == 0 ) { - if( control->ensemble == iNPT ) { - val = atof(tmp[1]); - control->P[0] = control->P[1] = control->P[2] = val; - } - else if( control->ensemble == sNPT ) { - val = atof(tmp[1]); - control->P[0] = val; - - val = atof(tmp[2]); - control->P[1] = val; - - val = atof(tmp[3]); - control->P[2] = val; - } - } - else if( strcmp(tmp[0], "p_mass") == 0 ) { - if( control->ensemble == iNPT ) { - val = atof(tmp[1]); - control->Tau_P[0] = val * 1.e-3; // convert p_mass from fs to ps - } - else if( control->ensemble == sNPT ) { - val = atof(tmp[1]); - control->Tau_P[0] = val * 1.e-3; // convert p_mass from fs to ps - - val = atof(tmp[2]); - control->Tau_P[1] = val * 1.e-3; // convert p_mass from fs to ps - - val = atof(tmp[3]); - control->Tau_P[2] = val * 1.e-3; // convert p_mass from fs to ps - } - } - else if( strcmp(tmp[0], "pt_mass") == 0 ) { - val = atof(tmp[1]); - control->Tau_PT = val * 1.e-3; // convert pt_mass from fs to ps - } - else if( strcmp(tmp[0], "compress") == 0 ) { - val = atof(tmp[1]); - control->compressibility = val; - } - else if( strcmp(tmp[0], "press_mode") == 0 ) { - val = atoi(tmp[1]); - control->press_mode = val; - } - else if( strcmp(tmp[0], "remove_CoM_vel") == 0 ) { - val = atoi(tmp[1]); - control->remove_CoM_vel = val; - } - else if( strcmp(tmp[0], "debug_level") == 0 ) { - ival = atoi(tmp[1]); - out_control->debug_level = ival; - } - else if( strcmp(tmp[0], "energy_update_freq") == 0 ) { - ival = atoi(tmp[1]); - out_control->energy_update_freq = ival; - } - else if( strcmp(tmp[0], "write_freq") == 0 ) { - ival = atoi(tmp[1]); - out_control->write_steps = ival; - } - else if( strcmp(tmp[0], "traj_compress") == 0 ) { - ival = atoi(tmp[1]); - out_control->traj_compress = ival; - - if( out_control->traj_compress ) - out_control->write = (int (*)(FILE *, const char *, ...)) gzprintf; - else out_control->write = fprintf; - } - else if( strcmp(tmp[0], "traj_format") == 0 ) { - ival = atoi(tmp[1]); - out_control->traj_format = ival; - - if( out_control->traj_format == 0 ) { - out_control->write_header = - (int (*)( reax_system*, control_params*, - static_storage*, void* )) Write_Custom_Header; - out_control->append_traj_frame = - (int (*)(reax_system*, control_params*, simulation_data*, - static_storage*, list **, void*)) Append_Custom_Frame; - } - else if( out_control->traj_format == 1 ) { - out_control->write_header = - (int (*)( reax_system*, control_params*, - static_storage*, void* )) Write_xyz_Header; - out_control->append_traj_frame = - (int (*)( reax_system*, control_params*, simulation_data*, - static_storage*, list **, void* )) Append_xyz_Frame; - } - } - else if( strcmp(tmp[0], "traj_title") == 0 ) { - strcpy( out_control->traj_title, tmp[1] ); - } - else if( strcmp(tmp[0], "atom_info") == 0 ) { - ival = atoi(tmp[1]); - out_control->atom_format += ival * 4; - } - else if( strcmp(tmp[0], "atom_velocities") == 0 ) { - ival = atoi(tmp[1]); - out_control->atom_format += ival * 2; - } - else if( strcmp(tmp[0], "atom_forces") == 0 ) { - ival = atoi(tmp[1]); - out_control->atom_format += ival * 1; - } - else if( strcmp(tmp[0], "bond_info") == 0 ) { - ival = atoi(tmp[1]); - out_control->bond_info = ival; - } - else if( strcmp(tmp[0], "angle_info") == 0 ) { - ival = atoi(tmp[1]); - out_control->angle_info = ival; - } - else if( strcmp(tmp[0], "test_forces") == 0 ) { - ival = atoi(tmp[1]); - } - else if( strcmp(tmp[0], "molec_anal") == 0 ) { - ival = atoi(tmp[1]); - control->molec_anal = ival; - } - else if( strcmp(tmp[0], "freq_molec_anal") == 0 ) { - ival = atoi(tmp[1]); - control->freq_molec_anal = ival; - } - else if( strcmp(tmp[0], "bond_graph_cutoff") == 0 ) { - val = atof(tmp[1]); - control->bg_cut = val; - } - else if( strcmp(tmp[0], "ignore") == 0 ) { - control->num_ignored = atoi(tmp[1]); - for( i = 0; i < control->num_ignored; ++i ) - control->ignore[atoi(tmp[i+2])] = 1; - } - else if( strcmp(tmp[0], "dipole_anal") == 0 ) { - ival = atoi(tmp[1]); - control->dipole_anal = ival; - } - else if( strcmp(tmp[0], "freq_dipole_anal") == 0 ) { - ival = atoi(tmp[1]); - control->freq_dipole_anal = ival; - } - else if( strcmp(tmp[0], "diffusion_coef") == 0 ) { - ival = atoi(tmp[1]); - control->diffusion_coef = ival; - } - else if( strcmp(tmp[0], "freq_diffusion_coef") == 0 ) { - ival = atoi(tmp[1]); - control->freq_diffusion_coef = ival; - } - else if( strcmp(tmp[0], "restrict_type") == 0 ) { - ival = atoi(tmp[1]); - control->restrict_type = ival; - } - else { - fprintf( stderr, "WARNING: unknown parameter %s\n", tmp[0] ); - exit( 15 ); + while (fgets(s, MAX_LINE, fp)) + { + c = Tokenize(s, &tmp); + + if ( strcmp(tmp[0], "simulation_name") == 0 ) + { + strcpy( control->sim_name, tmp[1] ); + } + //else if( strcmp(tmp[0], "restart") == 0 ) { + // ival = atoi(tmp[1]); + // control->restart = ival; + //} + else if ( strcmp(tmp[0], "restart_format") == 0 ) + { + ival = atoi(tmp[1]); + out_control->restart_format = ival; + } + else if ( strcmp(tmp[0], "restart_freq") == 0 ) + { + ival = atoi(tmp[1]); + out_control->restart_freq = ival; + } + else if ( strcmp(tmp[0], "random_vel") == 0 ) + { + ival = atoi(tmp[1]); + control->random_vel = ival; + } + else if ( strcmp(tmp[0], "reposition_atoms") == 0 ) + { + ival = atoi(tmp[1]); + control->reposition_atoms = ival; + } + else if ( strcmp(tmp[0], "ensemble_type") == 0 ) + { + ival = atoi(tmp[1]); + control->ensemble = ival; + } + else if ( strcmp(tmp[0], "nsteps") == 0 ) + { + ival = atoi(tmp[1]); + control->nsteps = ival; + } + else if ( strcmp(tmp[0], "dt") == 0 ) + { + val = atof(tmp[1]); + control->dt = val * 1.e-3; // convert dt from fs to ps! + } + else if ( strcmp(tmp[0], "periodic_boundaries") == 0 ) + { + ival = atoi( tmp[1] ); + control->periodic_boundaries = ival; + } + else if ( strcmp(tmp[0], "periodic_images") == 0 ) + { + ival = atoi(tmp[1]); + control->periodic_images[0] = ival; + ival = atoi(tmp[2]); + control->periodic_images[1] = ival; + ival = atoi(tmp[3]); + control->periodic_images[2] = ival; + } + else if ( strcmp(tmp[0], "geo_format") == 0 ) + { + ival = atoi( tmp[1] ); + control->geo_format = ival; + } + else if ( strcmp(tmp[0], "restrict_bonds") == 0 ) + { + ival = atoi( tmp[1] ); + control->restrict_bonds = ival; + } + else if ( strcmp(tmp[0], "tabulate_long_range") == 0 ) + { + ival = atoi( tmp[1] ); + control->tabulate = ival; + } + else if ( strcmp(tmp[0], "reneighbor") == 0 ) + { + ival = atoi( tmp[1] ); + control->reneighbor = ival; + } + else if ( strcmp(tmp[0], "vlist_buffer") == 0 ) + { + val = atof(tmp[1]); + control->vlist_cut = val; + } + else if ( strcmp(tmp[0], "nbrhood_cutoff") == 0 ) + { + val = atof(tmp[1]); + control->nbr_cut = val; + } + else if ( strcmp(tmp[0], "thb_cutoff") == 0 ) + { + val = atof(tmp[1]); + control->thb_cut = val; + } + else if ( strcmp(tmp[0], "hbond_cutoff") == 0 ) + { + val = atof( tmp[1] ); + control->hb_cut = val; + } + else if ( strcmp(tmp[0], "q_err") == 0 ) + { + val = atof( tmp[1] ); + control->q_err = val; + } + else if ( strcmp(tmp[0], "ilu_refactor") == 0 ) + { + ival = atoi( tmp[1] ); + control->refactor = ival; + } + else if ( strcmp(tmp[0], "ilu_droptol") == 0 ) + { + val = atof( tmp[1] ); + control->droptol = val; + } + else if ( strcmp(tmp[0], "temp_init") == 0 ) + { + val = atof(tmp[1]); + control->T_init = val; + + if ( control->T_init < 0.001 ) + control->T_init = 0.001; + } + else if ( strcmp(tmp[0], "temp_final") == 0 ) + { + val = atof(tmp[1]); + control->T_final = val; + + if ( control->T_final < 0.1 ) + control->T_final = 0.1; + } + else if ( strcmp(tmp[0], "t_mass") == 0 ) + { + val = atof(tmp[1]); + control->Tau_T = val * 1.e-3; // convert t_mass from fs to ps + } + else if ( strcmp(tmp[0], "t_mode") == 0 ) + { + ival = atoi(tmp[1]); + control->T_mode = ival; + } + else if ( strcmp(tmp[0], "t_rate") == 0 ) + { + val = atof(tmp[1]); + control->T_rate = val; + } + else if ( strcmp(tmp[0], "t_freq") == 0 ) + { + val = atof(tmp[1]); + control->T_freq = val; + } + else if ( strcmp(tmp[0], "pressure") == 0 ) + { + if ( control->ensemble == iNPT ) + { + val = atof(tmp[1]); + control->P[0] = control->P[1] = control->P[2] = val; + } + else if ( control->ensemble == sNPT ) + { + val = atof(tmp[1]); + control->P[0] = val; + + val = atof(tmp[2]); + control->P[1] = val; + + val = atof(tmp[3]); + control->P[2] = val; + } + } + else if ( strcmp(tmp[0], "p_mass") == 0 ) + { + if ( control->ensemble == iNPT ) + { + val = atof(tmp[1]); + control->Tau_P[0] = val * 1.e-3; // convert p_mass from fs to ps + } + else if ( control->ensemble == sNPT ) + { + val = atof(tmp[1]); + control->Tau_P[0] = val * 1.e-3; // convert p_mass from fs to ps + + val = atof(tmp[2]); + control->Tau_P[1] = val * 1.e-3; // convert p_mass from fs to ps + + val = atof(tmp[3]); + control->Tau_P[2] = val * 1.e-3; // convert p_mass from fs to ps + } + } + else if ( strcmp(tmp[0], "pt_mass") == 0 ) + { + val = atof(tmp[1]); + control->Tau_PT = val * 1.e-3; // convert pt_mass from fs to ps + } + else if ( strcmp(tmp[0], "compress") == 0 ) + { + val = atof(tmp[1]); + control->compressibility = val; + } + else if ( strcmp(tmp[0], "press_mode") == 0 ) + { + val = atoi(tmp[1]); + control->press_mode = val; + } + else if ( strcmp(tmp[0], "remove_CoM_vel") == 0 ) + { + val = atoi(tmp[1]); + control->remove_CoM_vel = val; + } + else if ( strcmp(tmp[0], "debug_level") == 0 ) + { + ival = atoi(tmp[1]); + out_control->debug_level = ival; + } + else if ( strcmp(tmp[0], "energy_update_freq") == 0 ) + { + ival = atoi(tmp[1]); + out_control->energy_update_freq = ival; + } + else if ( strcmp(tmp[0], "write_freq") == 0 ) + { + ival = atoi(tmp[1]); + out_control->write_steps = ival; + } + else if ( strcmp(tmp[0], "traj_compress") == 0 ) + { + ival = atoi(tmp[1]); + out_control->traj_compress = ival; + + if ( out_control->traj_compress ) + out_control->write = (int (*)(FILE *, const char *, ...)) gzprintf; + else out_control->write = fprintf; + } + else if ( strcmp(tmp[0], "traj_format") == 0 ) + { + ival = atoi(tmp[1]); + out_control->traj_format = ival; + + if ( out_control->traj_format == 0 ) + { + out_control->write_header = + (int (*)( reax_system*, control_params*, + static_storage*, void* )) Write_Custom_Header; + out_control->append_traj_frame = + (int (*)(reax_system*, control_params*, simulation_data*, + static_storage*, list **, void*)) Append_Custom_Frame; + } + else if ( out_control->traj_format == 1 ) + { + out_control->write_header = + (int (*)( reax_system*, control_params*, + static_storage*, void* )) Write_xyz_Header; + out_control->append_traj_frame = + (int (*)( reax_system*, control_params*, simulation_data*, + static_storage*, list **, void* )) Append_xyz_Frame; + } + } + else if ( strcmp(tmp[0], "traj_title") == 0 ) + { + strcpy( out_control->traj_title, tmp[1] ); + } + else if ( strcmp(tmp[0], "atom_info") == 0 ) + { + ival = atoi(tmp[1]); + out_control->atom_format += ival * 4; + } + else if ( strcmp(tmp[0], "atom_velocities") == 0 ) + { + ival = atoi(tmp[1]); + out_control->atom_format += ival * 2; + } + else if ( strcmp(tmp[0], "atom_forces") == 0 ) + { + ival = atoi(tmp[1]); + out_control->atom_format += ival * 1; + } + else if ( strcmp(tmp[0], "bond_info") == 0 ) + { + ival = atoi(tmp[1]); + out_control->bond_info = ival; + } + else if ( strcmp(tmp[0], "angle_info") == 0 ) + { + ival = atoi(tmp[1]); + out_control->angle_info = ival; + } + else if ( strcmp(tmp[0], "test_forces") == 0 ) + { + ival = atoi(tmp[1]); + } + else if ( strcmp(tmp[0], "molec_anal") == 0 ) + { + ival = atoi(tmp[1]); + control->molec_anal = ival; + } + else if ( strcmp(tmp[0], "freq_molec_anal") == 0 ) + { + ival = atoi(tmp[1]); + control->freq_molec_anal = ival; + } + else if ( strcmp(tmp[0], "bond_graph_cutoff") == 0 ) + { + val = atof(tmp[1]); + control->bg_cut = val; + } + else if ( strcmp(tmp[0], "ignore") == 0 ) + { + control->num_ignored = atoi(tmp[1]); + for ( i = 0; i < control->num_ignored; ++i ) + control->ignore[atoi(tmp[i + 2])] = 1; + } + else if ( strcmp(tmp[0], "dipole_anal") == 0 ) + { + ival = atoi(tmp[1]); + control->dipole_anal = ival; + } + else if ( strcmp(tmp[0], "freq_dipole_anal") == 0 ) + { + ival = atoi(tmp[1]); + control->freq_dipole_anal = ival; + } + else if ( strcmp(tmp[0], "diffusion_coef") == 0 ) + { + ival = atoi(tmp[1]); + control->diffusion_coef = ival; + } + else if ( strcmp(tmp[0], "freq_diffusion_coef") == 0 ) + { + ival = atoi(tmp[1]); + control->freq_diffusion_coef = ival; + } + else if ( strcmp(tmp[0], "restrict_type") == 0 ) + { + ival = atoi(tmp[1]); + control->restrict_type = ival; + } + else + { + fprintf( stderr, "WARNING: unknown parameter %s\n", tmp[0] ); + exit( 15 ); + } + } + + if (ferror(fp)) + { + fprintf(stderr, "Error reading control file. Terminating.\n"); + exit( INVALID_INPUT ); } - } - - if(ferror(fp)) - { - fprintf(stderr, "Error reading control file. Terminating.\n"); - exit( INVALID_INPUT ); - } - - /* determine target T */ - if( control->T_mode == 0 ) - control->T = control->T_final; - else control->T = control->T_init; + + /* determine target T */ + if ( control->T_mode == 0 ) + control->T = control->T_final; + else control->T = control->T_init; - /* near neighbor and far neighbor cutoffs */ - control->bo_cut = 0.01 * system->reaxprm.gp.l[29]; - control->r_low = system->reaxprm.gp.l[11]; - control->r_cut = system->reaxprm.gp.l[12]; - control->vlist_cut += control->r_cut; + /* near neighbor and far neighbor cutoffs */ + control->bo_cut = 0.01 * system->reaxprm.gp.l[29]; + control->r_low = system->reaxprm.gp.l[11]; + control->r_cut = system->reaxprm.gp.l[12]; + control->vlist_cut += control->r_cut; - system->g.cell_size = control->vlist_cut / 2.; - for( i = 0; i < 3; ++i ) - system->g.spread[i] = 2; + system->g.cell_size = control->vlist_cut / 2.; + for ( i = 0; i < 3; ++i ) + system->g.spread[i] = 2; - /* Initialize Taper function */ - Init_Taper( control ); + /* Initialize Taper function */ + Init_Taper( control ); - /* free memory allocations at the top */ - for( i = 0; i < MAX_TOKENS; i++ ) - free( tmp[i] ); - free( tmp ); - free( s ); + /* free memory allocations at the top */ + for ( i = 0; i < MAX_TOKENS; i++ ) + free( tmp[i] ); + free( tmp ); + free( s ); #if defined(DEBUG_FOCUS) - fprintf( stderr, - "en=%d steps=%d dt=%.5f opt=%d T=%.5f P=%.5f %.5f %.5f\n", - control->ensemble, control->nsteps, control->dt, control->tabulate, - control->T, control->P[0], control->P[1], control->P[2] ); + fprintf( stderr, + "en=%d steps=%d dt=%.5f opt=%d T=%.5f P=%.5f %.5f %.5f\n", + control->ensemble, control->nsteps, control->dt, control->tabulate, + control->T, control->P[0], control->P[1], control->P[2] ); - fprintf(stderr, "control file read\n" ); + fprintf(stderr, "control file read\n" ); #endif - return 0; + return 0; } diff --git a/puremd_rc_1003/sPuReMD/param.h b/puremd_rc_1003/sPuReMD/param.h index bd8661fe..838bb1a0 100644 --- a/puremd_rc_1003/sPuReMD/param.h +++ b/puremd_rc_1003/sPuReMD/param.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -34,7 +34,7 @@ int Tokenize( char*, char*** ); char Read_Force_Field( FILE*, reax_interaction* ); -char Read_Control_File( FILE*, reax_system*, control_params*, - output_controls* ); +char Read_Control_File( FILE*, reax_system*, control_params*, + output_controls* ); #endif diff --git a/puremd_rc_1003/sPuReMD/pdb_tools.c b/puremd_rc_1003/sPuReMD/pdb_tools.c index 0cd0331b..e7b1b57d 100644 --- a/puremd_rc_1003/sPuReMD/pdb_tools.c +++ b/puremd_rc_1003/sPuReMD/pdb_tools.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -29,546 +29,614 @@ int is_Valid_Serial( static_storage *workspace, int serial ) { - if( workspace->map_serials[ serial ] < 0 ) + if ( workspace->map_serials[ serial ] < 0 ) { - fprintf( stderr, "CONECT line includes invalid pdb serial number %d.\n", - serial ); - fprintf( stderr, "Please correct the input file.Terminating...\n" ); - exit( INVALID_INPUT ); + fprintf( stderr, "CONECT line includes invalid pdb serial number %d.\n", + serial ); + fprintf( stderr, "Please correct the input file.Terminating...\n" ); + exit( INVALID_INPUT ); } - - return 1; + + return 1; } int Check_Input_Range( int val, int lo, int hi, char *message ) { - if( val < lo || val > hi ) + if ( val < lo || val > hi ) { - fprintf( stderr, "%s\nInput %d - Out of range %d-%d. Terminating...\n", - message, val, lo, hi ); - exit( INVALID_INPUT ); + fprintf( stderr, "%s\nInput %d - Out of range %d-%d. Terminating...\n", + message, val, lo, hi ); + exit( INVALID_INPUT ); } - return 1; + return 1; } void Trim_Spaces( char *element ) { - int i, j; + int i, j; - for( i = 0; element[i] == ' '; ++i ); // skip initial space chars - - for( j = i; j < strlen(element) && element[j] != ' '; ++j ) - element[j-i] = toupper( element[j] ); // make uppercase, move to beginning - element[j-i] = 0; // finalize the string + for ( i = 0; element[i] == ' '; ++i ); // skip initial space chars + + for ( j = i; j < strlen(element) && element[j] != ' '; ++j ) + element[j - i] = toupper( element[j] ); // make uppercase, move to beginning + element[j - i] = 0; // finalize the string } -char Read_PDB( char* pdb_file, reax_system* system, control_params *control, - simulation_data *data, static_storage *workspace ) +char Read_PDB( char* pdb_file, reax_system* system, control_params *control, + simulation_data *data, static_storage *workspace ) { - FILE *pdb; - char **tmp; - char *s, *s1; - char descriptor[9], serial[9]; - char atom_name[9], res_name[9], res_seq[9]; - char s_x[9], s_y[9], s_z[9]; - char occupancy[9], temp_factor[9]; - char seg_id[9], element[9], charge[9]; - char alt_loc, chain_id, icode; - char s_a[10], s_b[10], s_c[10], s_alpha[9], s_beta[9], s_gamma[9]; - char s_group[12], s_zValue[9]; - char *endptr = NULL; - int i, c, c1, pdb_serial, ratom = 0; - /* open pdb file */ - if ( (pdb = fopen(pdb_file, "r")) == NULL ) { - fprintf( stderr, "Error opening the pdb file!\n" ); - exit( FILE_NOT_FOUND_ERR ); - } - - - /* allocate memory for tokenizing pdb lines */ - s = (char*) malloc( sizeof(char) * MAX_LINE ); - s1 = (char*) malloc( sizeof(char) * MAX_LINE ); - tmp = (char**) malloc( sizeof(char*) * MAX_TOKENS ); - for( i = 0; i < MAX_TOKENS; i++ ) - tmp[i] = (char*) malloc( sizeof(char) * MAX_TOKEN_LEN ); - - - /* count number of atoms in the pdb file */ - system->N = 0; - s[0] = 0; - while (fgets( s, MAX_LINE, pdb )) - { - - tmp[0][0] = 0; - c = Tokenize( s, &tmp ); - - if( strncmp( tmp[0], "ATOM", 4 ) == 0 || - strncmp( tmp[0], "HETATM", 6 ) == 0 ) - (system->N)++; + FILE *pdb; + char **tmp; + char *s, *s1; + char descriptor[9], serial[9]; + char atom_name[9], res_name[9], res_seq[9]; + char s_x[9], s_y[9], s_z[9]; + char occupancy[9], temp_factor[9]; + char seg_id[9], element[9], charge[9]; + char alt_loc, chain_id, icode; + char s_a[10], s_b[10], s_c[10], s_alpha[9], s_beta[9], s_gamma[9]; + char s_group[12], s_zValue[9]; + char *endptr = NULL; + int i, c, c1, pdb_serial, ratom = 0; + /* open pdb file */ + if ( (pdb = fopen(pdb_file, "r")) == NULL ) + { + fprintf( stderr, "Error opening the pdb file!\n" ); + exit( FILE_NOT_FOUND_ERR ); + } + + + /* allocate memory for tokenizing pdb lines */ + s = (char*) malloc( sizeof(char) * MAX_LINE ); + s1 = (char*) malloc( sizeof(char) * MAX_LINE ); + tmp = (char**) malloc( sizeof(char*) * MAX_TOKENS ); + for ( i = 0; i < MAX_TOKENS; i++ ) + tmp[i] = (char*) malloc( sizeof(char) * MAX_TOKEN_LEN ); + + + /* count number of atoms in the pdb file */ + system->N = 0; s[0] = 0; - } - if(ferror(pdb)) - { - fprintf(stderr, "Error reading PDB file. Terminating.\n"); - exit( INVALID_INPUT ); - } - - fclose(pdb); + while (fgets( s, MAX_LINE, pdb )) + { + + tmp[0][0] = 0; + c = Tokenize( s, &tmp ); + + if ( strncmp( tmp[0], "ATOM", 4 ) == 0 || + strncmp( tmp[0], "HETATM", 6 ) == 0 ) + (system->N)++; + s[0] = 0; + } + if (ferror(pdb)) + { + fprintf(stderr, "Error reading PDB file. Terminating.\n"); + exit( INVALID_INPUT ); + } + + fclose(pdb); #if defined(DEBUG_FOCUS) - fprintf( stderr, "system->N: %d\n", system->N ); + fprintf( stderr, "system->N: %d\n", system->N ); #endif - /* memory allocations for atoms, atom maps, bond restrictions */ - system->atoms = (reax_atom*) calloc( system->N, sizeof(reax_atom) ); - - workspace->map_serials = (int*) calloc( MAX_ATOM_ID, sizeof(int) ); - for( i = 0; i < MAX_ATOM_ID; ++i ) - workspace->map_serials[i] = -1; - - workspace->orig_id = (int*) calloc( system->N, sizeof(int) ); - workspace->restricted = (int*) calloc( system->N, sizeof(int) ); - workspace->restricted_list = (int**) calloc( system->N, sizeof(int*) ); - for( i = 0; i < system->N; ++i ) - workspace->restricted_list[i] = (int*) calloc( MAX_RESTRICT, sizeof(int) ); - - - /* start reading and processing pdb file */ - if ( (pdb = fopen(pdb_file,"r")) == NULL ) - { - fprintf( stderr, "Error opening the pdb file!\n" ); - exit( FILE_NOT_FOUND_ERR ); - } - c = 0; - c1 = 0; - - while (!feof(pdb)) { - /* clear previous input line */ - s[0] = 0; - for( i = 0; i < c1; ++i ) - tmp[i][0] = 0; - - /* read new line and tokenize it */ - fgets( s, MAX_LINE, pdb ); - strncpy( s1, s, MAX_LINE-1 ); - c1 = Tokenize( s, &tmp ); - - /* process new line */ - if( strncmp(tmp[0],"ATOM",4) == 0 || strncmp(tmp[0],"HETATM", 6) == 0 ) { - if( strncmp(tmp[0],"ATOM",4) == 0 ) { - strncpy( &descriptor[0], s1, 6 ); descriptor[6] = 0; - strncpy( &serial[0], s1+6, 5 ); serial[5] = 0; - strncpy( &atom_name[0], s1+12, 4 ); atom_name[4] = 0; - alt_loc = s1[16]; - strncpy( &res_name[0], s1+17, 3 ); res_name[3] = 0; - chain_id = s1[21]; - strncpy( &res_seq[0], s1+22, 4 ); res_seq[4] = 0; - icode = s1[26]; - strncpy( &s_x[0], s1+30, 8 ); s_x[8] = 0; - strncpy( &s_y[0], s1+38, 8 ); s_y[8] = 0; - strncpy( &s_z[0], s1+46, 8 ); s_z[8] = 0; - strncpy( &occupancy[0], s1+54, 6 ); occupancy[6] = 0; - strncpy( &temp_factor[0], s1+60, 6 ); temp_factor[6] = 0; - strncpy( &seg_id[0], s1+72, 4 ); seg_id[4] = 0; - strncpy( &element[0], s1+76, 2 ); element[2] = 0; - strncpy( &charge[0], s1+78, 2 ); charge[2] = 0; - } - else if (strncmp(tmp[0],"HETATM", 6) == 0) { - strncpy( &descriptor[0], s1, 6 ); descriptor[6] = 0; - strncpy( &serial[0], s1+6, 5 ); serial[5] = 0; - strncpy( &atom_name[0], s1+12, 4 ); atom_name[4] = 0; - alt_loc = s1[16]; - strncpy( &res_name[0], s1+17, 3 ); res_name[3] = 0; - chain_id = s1[21]; - strncpy( &res_seq[0], s1+22, 4 ); res_seq[4] = 0; - icode = s1[26]; - strncpy( &s_x[0], s1+30, 8 ); s_x[8] = 0; - strncpy( &s_y[0], s1+38, 8 ); s_y[8] = 0; - strncpy( &s_z[0], s1+46, 8 ); s_z[8] = 0; - strncpy( &occupancy[0], s1+54, 6 ); occupancy[6] = 0; - strncpy( &temp_factor[0], s1+60, 6 ); temp_factor[6] = 0; - //strncpy( &seg_id[0], s1+72, 4 ); seg_id[4] = 0; - strncpy( &element[0], s1+76, 2 ); element[2] = 0; - strncpy( &charge[0], s1+78, 2 ); charge[2] = 0; - } - - - /* add to mapping */ - pdb_serial = strtod( &serial[0], &endptr ); - Check_Input_Range( pdb_serial, 0, MAX_ATOM_ID, "Invalid pdb_serial" ); - workspace->map_serials[ pdb_serial ] = c; - workspace->orig_id[ c ] = pdb_serial; - // fprintf( stderr, "map %d --> %d\n", pdb_serial, c ); - - - /* copy atomic positions */ - system->atoms[c].x[0] = strtod( &s_x[0], &endptr ); - system->atoms[c].x[1] = strtod( &s_y[0], &endptr ); - system->atoms[c].x[2] = strtod( &s_z[0], &endptr ); - - /* atom name and type */ - strcpy( system->atoms[c].name, atom_name ); - Trim_Spaces( element ); - system->atoms[c].type = Get_Atom_Type( &(system->reaxprm), element ); - - /* fprintf( stderr, - "%d%8.3f%8.3f%8.3fq:%8.3f occ:%s temp:%s seg_id:%s element:%s\n", - system->atoms[c].type, - system->atoms[c].x[0], system->atoms[c].x[1], system->atoms[c].x[2], - system->atoms[c].q, occupancy, temp_factor, seg_id, element ); */ - c++; + /* memory allocations for atoms, atom maps, bond restrictions */ + system->atoms = (reax_atom*) calloc( system->N, sizeof(reax_atom) ); + + workspace->map_serials = (int*) calloc( MAX_ATOM_ID, sizeof(int) ); + for ( i = 0; i < MAX_ATOM_ID; ++i ) + workspace->map_serials[i] = -1; + + workspace->orig_id = (int*) calloc( system->N, sizeof(int) ); + workspace->restricted = (int*) calloc( system->N, sizeof(int) ); + workspace->restricted_list = (int**) calloc( system->N, sizeof(int*) ); + for ( i = 0; i < system->N; ++i ) + workspace->restricted_list[i] = (int*) calloc( MAX_RESTRICT, sizeof(int) ); + + + /* start reading and processing pdb file */ + if ( (pdb = fopen(pdb_file, "r")) == NULL ) + { + fprintf( stderr, "Error opening the pdb file!\n" ); + exit( FILE_NOT_FOUND_ERR ); } - else if(!strncmp( tmp[0], "CRYST1", 6 )) { - sscanf( s1, PDB_CRYST1_FORMAT, - &descriptor[0], - &s_a[0], - &s_b[0], - &s_c[0], - &s_alpha[0], - &s_beta[0], - &s_gamma[0], - &s_group[0], - &s_zValue[0] ); - - /* Compute full volume tensor from the angles */ - Init_Box_From_CRYST( atof(s_a), atof(s_b), atof(s_c), - atof(s_alpha), atof(s_beta), atof(s_gamma), - &(system->box) ); + c = 0; + c1 = 0; + + while (!feof(pdb)) + { + /* clear previous input line */ + s[0] = 0; + for ( i = 0; i < c1; ++i ) + tmp[i][0] = 0; + + /* read new line and tokenize it */ + fgets( s, MAX_LINE, pdb ); + strncpy( s1, s, MAX_LINE - 1 ); + c1 = Tokenize( s, &tmp ); + + /* process new line */ + if ( strncmp(tmp[0], "ATOM", 4) == 0 || strncmp(tmp[0], "HETATM", 6) == 0 ) + { + if ( strncmp(tmp[0], "ATOM", 4) == 0 ) + { + strncpy( &descriptor[0], s1, 6 ); + descriptor[6] = 0; + strncpy( &serial[0], s1 + 6, 5 ); + serial[5] = 0; + strncpy( &atom_name[0], s1 + 12, 4 ); + atom_name[4] = 0; + alt_loc = s1[16]; + strncpy( &res_name[0], s1 + 17, 3 ); + res_name[3] = 0; + chain_id = s1[21]; + strncpy( &res_seq[0], s1 + 22, 4 ); + res_seq[4] = 0; + icode = s1[26]; + strncpy( &s_x[0], s1 + 30, 8 ); + s_x[8] = 0; + strncpy( &s_y[0], s1 + 38, 8 ); + s_y[8] = 0; + strncpy( &s_z[0], s1 + 46, 8 ); + s_z[8] = 0; + strncpy( &occupancy[0], s1 + 54, 6 ); + occupancy[6] = 0; + strncpy( &temp_factor[0], s1 + 60, 6 ); + temp_factor[6] = 0; + strncpy( &seg_id[0], s1 + 72, 4 ); + seg_id[4] = 0; + strncpy( &element[0], s1 + 76, 2 ); + element[2] = 0; + strncpy( &charge[0], s1 + 78, 2 ); + charge[2] = 0; + } + else if (strncmp(tmp[0], "HETATM", 6) == 0) + { + strncpy( &descriptor[0], s1, 6 ); + descriptor[6] = 0; + strncpy( &serial[0], s1 + 6, 5 ); + serial[5] = 0; + strncpy( &atom_name[0], s1 + 12, 4 ); + atom_name[4] = 0; + alt_loc = s1[16]; + strncpy( &res_name[0], s1 + 17, 3 ); + res_name[3] = 0; + chain_id = s1[21]; + strncpy( &res_seq[0], s1 + 22, 4 ); + res_seq[4] = 0; + icode = s1[26]; + strncpy( &s_x[0], s1 + 30, 8 ); + s_x[8] = 0; + strncpy( &s_y[0], s1 + 38, 8 ); + s_y[8] = 0; + strncpy( &s_z[0], s1 + 46, 8 ); + s_z[8] = 0; + strncpy( &occupancy[0], s1 + 54, 6 ); + occupancy[6] = 0; + strncpy( &temp_factor[0], s1 + 60, 6 ); + temp_factor[6] = 0; + //strncpy( &seg_id[0], s1+72, 4 ); seg_id[4] = 0; + strncpy( &element[0], s1 + 76, 2 ); + element[2] = 0; + strncpy( &charge[0], s1 + 78, 2 ); + charge[2] = 0; + } + + + /* add to mapping */ + pdb_serial = strtod( &serial[0], &endptr ); + Check_Input_Range( pdb_serial, 0, MAX_ATOM_ID, "Invalid pdb_serial" ); + workspace->map_serials[ pdb_serial ] = c; + workspace->orig_id[ c ] = pdb_serial; + // fprintf( stderr, "map %d --> %d\n", pdb_serial, c ); + + + /* copy atomic positions */ + system->atoms[c].x[0] = strtod( &s_x[0], &endptr ); + system->atoms[c].x[1] = strtod( &s_y[0], &endptr ); + system->atoms[c].x[2] = strtod( &s_z[0], &endptr ); + + /* atom name and type */ + strcpy( system->atoms[c].name, atom_name ); + Trim_Spaces( element ); + system->atoms[c].type = Get_Atom_Type( &(system->reaxprm), element ); + + /* fprintf( stderr, + "%d%8.3f%8.3f%8.3fq:%8.3f occ:%s temp:%s seg_id:%s element:%s\n", + system->atoms[c].type, + system->atoms[c].x[0], system->atoms[c].x[1], system->atoms[c].x[2], + system->atoms[c].q, occupancy, temp_factor, seg_id, element ); */ + c++; + } + else if (!strncmp( tmp[0], "CRYST1", 6 )) + { + sscanf( s1, PDB_CRYST1_FORMAT, + &descriptor[0], + &s_a[0], + &s_b[0], + &s_c[0], + &s_alpha[0], + &s_beta[0], + &s_gamma[0], + &s_group[0], + &s_zValue[0] ); + + /* Compute full volume tensor from the angles */ + Init_Box_From_CRYST( atof(s_a), atof(s_b), atof(s_c), + atof(s_alpha), atof(s_beta), atof(s_gamma), + &(system->box) ); + } + + /* IMPORTANT: We do not check for the soundness of restrictions here. + When atom2 is on atom1's restricted list, and there is a restriction on + atom2, then atom1 has to be on atom2's restricted list, too. However, + we do not check if this is the case in the input file, + this is upto the user. */ + else if (!strncmp( tmp[0], "CONECT", 6 )) + { + /* error check */ + //fprintf(stderr, "CONECT: %d\n", c1 ); + Check_Input_Range( c1 - 2, 0, MAX_RESTRICT, + "CONECT line exceeds max restrictions allowed.\n" ); + + /* read bond restrictions */ + if ( is_Valid_Serial( workspace, pdb_serial = atoi(tmp[1]) ) ) + ratom = workspace->map_serials[ pdb_serial ]; + + workspace->restricted[ ratom ] = c1 - 2; + for ( i = 2; i < c1; ++i ) + { + if ( is_Valid_Serial( workspace, pdb_serial = atoi(tmp[i]) ) ) + workspace->restricted_list[ ratom ][ i - 2 ] = + workspace->map_serials[ pdb_serial ]; + } + + /* fprintf( stderr, "restriction on %d:", ratom ); + for( i = 0; i < workspace->restricted[ ratom ]; ++i ) + fprintf( stderr, " %d", workspace->restricted_list[ratom][i] ); + fprintf( stderr, "\n" ); */ + } } - /* IMPORTANT: We do not check for the soundness of restrictions here. - When atom2 is on atom1's restricted list, and there is a restriction on - atom2, then atom1 has to be on atom2's restricted list, too. However, - we do not check if this is the case in the input file, - this is upto the user. */ - else if(!strncmp( tmp[0], "CONECT", 6 )) { - /* error check */ - //fprintf(stderr, "CONECT: %d\n", c1 ); - Check_Input_Range( c1 - 2, 0, MAX_RESTRICT, - "CONECT line exceeds max restrictions allowed.\n" ); - - /* read bond restrictions */ - if( is_Valid_Serial( workspace, pdb_serial = atoi(tmp[1]) ) ) - ratom = workspace->map_serials[ pdb_serial ]; - - workspace->restricted[ ratom ] = c1 - 2; - for( i = 2; i < c1; ++i ) - { - if( is_Valid_Serial( workspace, pdb_serial = atoi(tmp[i]) ) ) - workspace->restricted_list[ ratom ][ i-2 ] = - workspace->map_serials[ pdb_serial ]; - } - - /* fprintf( stderr, "restriction on %d:", ratom ); - for( i = 0; i < workspace->restricted[ ratom ]; ++i ) - fprintf( stderr, " %d", workspace->restricted_list[ratom][i] ); - fprintf( stderr, "\n" ); */ - } - } - - fclose(pdb); + fclose(pdb); #if defined(DEBUG_FOCUS) - fprintf( stderr, "pdb file read\n" ); + fprintf( stderr, "pdb file read\n" ); #endif - return 1; + return 1; } -char Write_PDB( reax_system* system, control_params *control, - simulation_data *data, static_storage *workspace, - list* bonds, output_controls *out_control ) +char Write_PDB( reax_system* system, control_params *control, + simulation_data *data, static_storage *workspace, + list* bonds, output_controls *out_control ) { - int i, j, k, count; - int connect[4]; - char temp[MAX_STR], name[10]; - real bo; - real alpha, beta, gamma; - - - /* open output pdb file */ - sprintf( temp, "%s%d.pdb", control->sim_name, data->step ); - if ( (out_control->pdb = fopen( temp, "w" )) == NULL ) - { - fprintf( stderr, "Error opening the pdb output file!\n" ); - exit( FILE_NOT_FOUND_ERR ); - } - - - /* Writing Box information */ - /* Write full volume tensor from the angles (as soon as possible) TODO_SOON */ - gamma = acos( (system->box.box[0][0] * system->box.box[1][0] + - system->box.box[0][1] * system->box.box[1][1] + - system->box.box[0][2] * system->box.box[1][2]) / - (system->box.box_norms[0]*system->box.box_norms[1])); - beta = acos( (system->box.box[0][0] * system->box.box[2][0] + - system->box.box[0][1] * system->box.box[2][1] + - system->box.box[0][2] * system->box.box[2][2]) / - (system->box.box_norms[0]*system->box.box_norms[2])); - alpha = acos( (system->box.box[2][0] * system->box.box[1][0] + - system->box.box[2][1] * system->box.box[1][1] + - system->box.box[2][2] * system->box.box[1][2]) / - (system->box.box_norms[2]*system->box.box_norms[1])); - - fprintf(out_control->pdb,PDB_CRYST1_FORMAT_O, - "CRYST1", - system->box.box_norms[0], - system->box.box_norms[1], - system->box.box_norms[2], - RAD2DEG(alpha), - RAD2DEG(beta), - RAD2DEG(gamma), - " ", - 0); - fprintf( out_control->log, "Box written\n" ); fflush( out_control->log ); - - /* Writing atom information */ - for (i=0; i < system->N; i++) { - strncpy( name, system->reaxprm.sbp[system->atoms[i].type].name, 2 ); - name[2] = '\0'; - fprintf( out_control->pdb,PDB_ATOM_FORMAT_O, - "ATOM ", - workspace->orig_id[i], - name, - ' ', - "REX", - ' ', - 1, - ' ', - system->atoms[i].x[0], - system->atoms[i].x[1], - system->atoms[i].x[2], - 1.0, - 0.0, - "0", - name, - " " ); - } - - fprintf( out_control->log, "ATOM written\n" ); fflush( out_control->log ); - - /* Writing connect information */ - for(i=0; i < system->N; i++) { - count = 0; - - for(j = Start_Index(i, bonds); j < End_Index(i, bonds); ++j) { - bo = bonds->select.bond_list[j].bo_data.BO; - if (bo > 0.3) - { - connect[count]=workspace->orig_id[bonds->select.bond_list[j].nbr]; - count++; - } + int i, j, k, count; + int connect[4]; + char temp[MAX_STR], name[10]; + real bo; + real alpha, beta, gamma; + + + /* open output pdb file */ + sprintf( temp, "%s%d.pdb", control->sim_name, data->step ); + if ( (out_control->pdb = fopen( temp, "w" )) == NULL ) + { + fprintf( stderr, "Error opening the pdb output file!\n" ); + exit( FILE_NOT_FOUND_ERR ); } - fprintf( out_control->pdb, "%6s%6d", "CONECT", workspace->orig_id[i] ); - for( k=0; k < count; k++ ) - fprintf( out_control->pdb, "%6d", connect[k] ); - fprintf( out_control->pdb, "\n" ); - } - fprintf( out_control->pdb, "END\n" ); + /* Writing Box information */ + /* Write full volume tensor from the angles (as soon as possible) TODO_SOON */ + gamma = acos( (system->box.box[0][0] * system->box.box[1][0] + + system->box.box[0][1] * system->box.box[1][1] + + system->box.box[0][2] * system->box.box[1][2]) / + (system->box.box_norms[0] * system->box.box_norms[1])); + beta = acos( (system->box.box[0][0] * system->box.box[2][0] + + system->box.box[0][1] * system->box.box[2][1] + + system->box.box[0][2] * system->box.box[2][2]) / + (system->box.box_norms[0] * system->box.box_norms[2])); + alpha = acos( (system->box.box[2][0] * system->box.box[1][0] + + system->box.box[2][1] * system->box.box[1][1] + + system->box.box[2][2] * system->box.box[1][2]) / + (system->box.box_norms[2] * system->box.box_norms[1])); + + fprintf(out_control->pdb, PDB_CRYST1_FORMAT_O, + "CRYST1", + system->box.box_norms[0], + system->box.box_norms[1], + system->box.box_norms[2], + RAD2DEG(alpha), + RAD2DEG(beta), + RAD2DEG(gamma), + " ", + 0); + fprintf( out_control->log, "Box written\n" ); + fflush( out_control->log ); + + /* Writing atom information */ + for (i = 0; i < system->N; i++) + { + strncpy( name, system->reaxprm.sbp[system->atoms[i].type].name, 2 ); + name[2] = '\0'; + fprintf( out_control->pdb, PDB_ATOM_FORMAT_O, + "ATOM ", + workspace->orig_id[i], + name, + ' ', + "REX", + ' ', + 1, + ' ', + system->atoms[i].x[0], + system->atoms[i].x[1], + system->atoms[i].x[2], + 1.0, + 0.0, + "0", + name, + " " ); + } - fclose( out_control->pdb ); + fprintf( out_control->log, "ATOM written\n" ); + fflush( out_control->log ); + + /* Writing connect information */ + for (i = 0; i < system->N; i++) + { + count = 0; + + for (j = Start_Index(i, bonds); j < End_Index(i, bonds); ++j) + { + bo = bonds->select.bond_list[j].bo_data.BO; + if (bo > 0.3) + { + connect[count] = workspace->orig_id[bonds->select.bond_list[j].nbr]; + count++; + } + } + + fprintf( out_control->pdb, "%6s%6d", "CONECT", workspace->orig_id[i] ); + for ( k = 0; k < count; k++ ) + fprintf( out_control->pdb, "%6d", connect[k] ); + fprintf( out_control->pdb, "\n" ); + } - return 1; + fprintf( out_control->pdb, "END\n" ); + + fclose( out_control->pdb ); + + return 1; } -char Read_BGF( char* bgf_file, reax_system* system, control_params *control, - simulation_data *data, static_storage *workspace ) +char Read_BGF( char* bgf_file, reax_system* system, control_params *control, + simulation_data *data, static_storage *workspace ) { - FILE *bgf; - char **tokens; - char *line, *backup; - char descriptor[10], serial[10]; - char atom_name[10], res_name[10], res_seq[10]; - char s_x[12], s_y[12], s_z[12]; - char occupancy[10], temp_factor[10]; - char element[10], charge[10]; - char chain_id; - char s_a[12], s_b[12], s_c[12], s_alpha[12], s_beta[12], s_gamma[12]; - char *endptr = NULL; - int i, atom_cnt, token_cnt, bgf_serial, ratom = 0; - - /* open biograf file */ - if ( (bgf = fopen( bgf_file, "r" )) == NULL ) + FILE *bgf; + char **tokens; + char *line, *backup; + char descriptor[10], serial[10]; + char atom_name[10], res_name[10], res_seq[10]; + char s_x[12], s_y[12], s_z[12]; + char occupancy[10], temp_factor[10]; + char element[10], charge[10]; + char chain_id; + char s_a[12], s_b[12], s_c[12], s_alpha[12], s_beta[12], s_gamma[12]; + char *endptr = NULL; + int i, atom_cnt, token_cnt, bgf_serial, ratom = 0; + + /* open biograf file */ + if ( (bgf = fopen( bgf_file, "r" )) == NULL ) + { + fprintf( stderr, "Error opening the bgf file!\n" ); + exit( FILE_NOT_FOUND_ERR ); + } + + + /* allocate memory for tokenizing biograf file lines */ + line = (char*) malloc( sizeof(char) * MAX_LINE ); + backup = (char*) malloc( sizeof(char) * MAX_LINE ); + tokens = (char**) malloc( sizeof(char*) * MAX_TOKENS ); + for ( i = 0; i < MAX_TOKENS; i++ ) + tokens[i] = (char*) malloc( sizeof(char) * MAX_TOKEN_LEN ); + + + /* count number of atoms in the pdb file */ + system->N = 0; + while ( !feof( bgf ) ) { - fprintf( stderr, "Error opening the bgf file!\n" ); - exit( FILE_NOT_FOUND_ERR ); + line[0] = 0; + fgets( line, MAX_LINE, bgf ); + + tokens[0][0] = 0; + token_cnt = Tokenize( line, &tokens ); + + if ( !strcmp( tokens[0], "ATOM" ) || !strcmp( tokens[0], "HETATM" ) ) + (system->N)++; } + //fprintf( stderr, "system->N: %d\n", system->N ); + fclose( bgf ); + + + /* memory allocations for atoms, atom maps, bond restrictions */ + system->atoms = (reax_atom*) calloc( system->N, sizeof(reax_atom) ); + + workspace->map_serials = (int*) calloc( MAX_ATOM_ID, sizeof(int) ); + for ( i = 0; i < MAX_ATOM_ID; ++i ) + workspace->map_serials[i] = -1; + workspace->orig_id = (int*) calloc( system->N, sizeof(int) ); + workspace->restricted = (int*) calloc( system->N, sizeof(int) ); + workspace->restricted_list = (int**) calloc( system->N, sizeof(int*) ); + for ( i = 0; i < system->N; ++i ) + workspace->restricted_list[i] = (int*) calloc( MAX_RESTRICT, sizeof(int) ); - /* allocate memory for tokenizing biograf file lines */ - line = (char*) malloc( sizeof(char) * MAX_LINE ); - backup = (char*) malloc( sizeof(char) * MAX_LINE ); - tokens = (char**) malloc( sizeof(char*) * MAX_TOKENS ); - for( i = 0; i < MAX_TOKENS; i++ ) - tokens[i] = (char*) malloc( sizeof(char) * MAX_TOKEN_LEN ); - - - /* count number of atoms in the pdb file */ - system->N = 0; - while( !feof( bgf ) ) { - line[0] = 0; - fgets( line, MAX_LINE, bgf ); - - tokens[0][0] = 0; - token_cnt = Tokenize( line, &tokens ); - - if( !strcmp( tokens[0], "ATOM" ) || !strcmp( tokens[0], "HETATM" ) ) - (system->N)++; - } - //fprintf( stderr, "system->N: %d\n", system->N ); - fclose( bgf ); - - - /* memory allocations for atoms, atom maps, bond restrictions */ - system->atoms = (reax_atom*) calloc( system->N, sizeof(reax_atom) ); - - workspace->map_serials = (int*) calloc( MAX_ATOM_ID, sizeof(int) ); - for( i = 0; i < MAX_ATOM_ID; ++i ) - workspace->map_serials[i] = -1; - - workspace->orig_id = (int*) calloc( system->N, sizeof(int) ); - workspace->restricted = (int*) calloc( system->N, sizeof(int) ); - workspace->restricted_list = (int**) calloc( system->N, sizeof(int*) ); - for( i = 0; i < system->N; ++i ) - workspace->restricted_list[i] = (int*) calloc( MAX_RESTRICT, sizeof(int) ); - - - /* start reading and processing bgf file */ - if ( (bgf = fopen( bgf_file, "r" )) == NULL ) - { - fprintf( stderr, "Error opening the bgf file!\n" ); - exit( FILE_NOT_FOUND_ERR ); - } - atom_cnt = 0; - token_cnt = 0; - - while( !feof( bgf ) ) { - /* clear previous input line */ - line[0] = 0; - for( i = 0; i < token_cnt; ++i ) - tokens[i][0] = 0; - - /* read new line and tokenize it */ - fgets( line, MAX_LINE, bgf ); - strncpy( backup, line, MAX_LINE-1 ); - token_cnt = Tokenize( line, &tokens ); - - /* process new line */ - if( !strncmp(tokens[0], "ATOM", 4) || !strncmp(tokens[0], "HETATM", 6) ) { - if( !strncmp(tokens[0], "ATOM", 4) ) { - strncpy( &descriptor[0], backup, 6 ); descriptor[6] = 0; - strncpy( &serial[0], backup+7, 5 ); serial[5] = 0; - strncpy( &atom_name[0], backup+13, 5 ); atom_name[5] = 0; - strncpy( &res_name[0], backup+19, 3 ); res_name[3] = 0; - chain_id = backup[23]; - strncpy( &res_seq[0], backup+25, 5 ); res_seq[5] = 0; - strncpy( &s_x[0], backup+30, 10 ); s_x[10] = 0; - strncpy( &s_y[0], backup+40, 10 ); s_y[10] = 0; - strncpy( &s_z[0], backup+50, 10 ); s_z[10] = 0; - strncpy( &element[0], backup+61, 5 ); element[5] = 0; - strncpy( &occupancy[0], backup+66, 3 ); occupancy[3] = 0; - strncpy( &temp_factor[0], backup+69, 2 ); temp_factor[2] = 0; - strncpy( &charge[0], backup+72, 8 ); charge[8] = 0; - } - else if( !strncmp(tokens[0],"HETATM", 6) ) { - /* bgf hetatm: - (7x,i5,1x,a5,1x,a3,1x,a1,1x,a5,3f10.5,1x,a5,i3,i2,1x,f8.5) */ - strncpy( &descriptor[0], backup, 6 ); descriptor[6] = 0; - strncpy( &serial[0], backup+7, 5 ); serial[5] = 0; - strncpy( &atom_name[0], backup+13, 5 ); atom_name[5] = 0; - strncpy( &res_name[0], backup+19, 3 ); res_name[3] = 0; - chain_id = backup[23]; - strncpy( &res_seq[0], backup+25, 5 ); res_seq[5] = 0; - strncpy( &s_x[0], backup+30, 10 ); s_x[10] = 0; - strncpy( &s_y[0], backup+40, 10 ); s_y[10] = 0; - strncpy( &s_z[0], backup+50, 10 ); s_z[10] = 0; - strncpy( &element[0], backup+61, 5 ); element[5] = 0; - strncpy( &occupancy[0], backup+66, 3 ); occupancy[3] = 0; - strncpy( &temp_factor[0], backup+69, 2 ); temp_factor[2] = 0; - strncpy( &charge[0], backup+72, 8 ); charge[8] = 0; - } - - - /* add to mapping */ - bgf_serial = strtod( &serial[0], &endptr ); - Check_Input_Range( bgf_serial, 0, MAX_ATOM_ID, "Invalid bgf serial" ); - workspace->map_serials[ bgf_serial ] = atom_cnt; - workspace->orig_id[ atom_cnt ] = bgf_serial; - // fprintf( stderr, "map %d --> %d\n", bgf_serial, atom_cnt ); - - - /* copy atomic positions */ - system->atoms[atom_cnt].x[0] = strtod( &s_x[0], &endptr ); - system->atoms[atom_cnt].x[1] = strtod( &s_y[0], &endptr ); - system->atoms[atom_cnt].x[2] = strtod( &s_z[0], &endptr ); - - - /* atom name and type */ - strcpy( system->atoms[atom_cnt].name, atom_name ); - Trim_Spaces( element ); - system->atoms[atom_cnt].type = - Get_Atom_Type( &(system->reaxprm), element ); - - /* fprintf( stderr, - "a:%3d(%1d) c:%10.5f%10.5f%10.5f q:%10.5f occ:%s temp:%s seg_id:%s element:%s\n", - atom_cnt, system->atoms[ atom_cnt ].type, - system->atoms[ atom_cnt ].x[0], - system->atoms[ atom_cnt ].x[1], system->atoms[ atom_cnt ].x[2], - system->atoms[ atom_cnt ].q, occupancy, temp_factor, - seg_id, element ); */ - - atom_cnt++; + + /* start reading and processing bgf file */ + if ( (bgf = fopen( bgf_file, "r" )) == NULL ) + { + fprintf( stderr, "Error opening the bgf file!\n" ); + exit( FILE_NOT_FOUND_ERR ); } - else if(!strncmp( tokens[0], "CRYSTX", 6 )) { - sscanf( backup, BGF_CRYSTX_FORMAT, - &descriptor[0], - &s_a[0], - &s_b[0], - &s_c[0], - &s_alpha[0], - &s_beta[0], - &s_gamma[0] ); - - /* Compute full volume tensor from the angles */ - Init_Box_From_CRYST( atof(s_a), atof(s_b), atof(s_c), - atof(s_alpha), atof(s_beta), atof(s_gamma), - &(system->box) ); + atom_cnt = 0; + token_cnt = 0; + + while ( !feof( bgf ) ) + { + /* clear previous input line */ + line[0] = 0; + for ( i = 0; i < token_cnt; ++i ) + tokens[i][0] = 0; + + /* read new line and tokenize it */ + fgets( line, MAX_LINE, bgf ); + strncpy( backup, line, MAX_LINE - 1 ); + token_cnt = Tokenize( line, &tokens ); + + /* process new line */ + if ( !strncmp(tokens[0], "ATOM", 4) || !strncmp(tokens[0], "HETATM", 6) ) + { + if ( !strncmp(tokens[0], "ATOM", 4) ) + { + strncpy( &descriptor[0], backup, 6 ); + descriptor[6] = 0; + strncpy( &serial[0], backup + 7, 5 ); + serial[5] = 0; + strncpy( &atom_name[0], backup + 13, 5 ); + atom_name[5] = 0; + strncpy( &res_name[0], backup + 19, 3 ); + res_name[3] = 0; + chain_id = backup[23]; + strncpy( &res_seq[0], backup + 25, 5 ); + res_seq[5] = 0; + strncpy( &s_x[0], backup + 30, 10 ); + s_x[10] = 0; + strncpy( &s_y[0], backup + 40, 10 ); + s_y[10] = 0; + strncpy( &s_z[0], backup + 50, 10 ); + s_z[10] = 0; + strncpy( &element[0], backup + 61, 5 ); + element[5] = 0; + strncpy( &occupancy[0], backup + 66, 3 ); + occupancy[3] = 0; + strncpy( &temp_factor[0], backup + 69, 2 ); + temp_factor[2] = 0; + strncpy( &charge[0], backup + 72, 8 ); + charge[8] = 0; + } + else if ( !strncmp(tokens[0], "HETATM", 6) ) + { + /* bgf hetatm: + (7x,i5,1x,a5,1x,a3,1x,a1,1x,a5,3f10.5,1x,a5,i3,i2,1x,f8.5) */ + strncpy( &descriptor[0], backup, 6 ); + descriptor[6] = 0; + strncpy( &serial[0], backup + 7, 5 ); + serial[5] = 0; + strncpy( &atom_name[0], backup + 13, 5 ); + atom_name[5] = 0; + strncpy( &res_name[0], backup + 19, 3 ); + res_name[3] = 0; + chain_id = backup[23]; + strncpy( &res_seq[0], backup + 25, 5 ); + res_seq[5] = 0; + strncpy( &s_x[0], backup + 30, 10 ); + s_x[10] = 0; + strncpy( &s_y[0], backup + 40, 10 ); + s_y[10] = 0; + strncpy( &s_z[0], backup + 50, 10 ); + s_z[10] = 0; + strncpy( &element[0], backup + 61, 5 ); + element[5] = 0; + strncpy( &occupancy[0], backup + 66, 3 ); + occupancy[3] = 0; + strncpy( &temp_factor[0], backup + 69, 2 ); + temp_factor[2] = 0; + strncpy( &charge[0], backup + 72, 8 ); + charge[8] = 0; + } + + + /* add to mapping */ + bgf_serial = strtod( &serial[0], &endptr ); + Check_Input_Range( bgf_serial, 0, MAX_ATOM_ID, "Invalid bgf serial" ); + workspace->map_serials[ bgf_serial ] = atom_cnt; + workspace->orig_id[ atom_cnt ] = bgf_serial; + // fprintf( stderr, "map %d --> %d\n", bgf_serial, atom_cnt ); + + + /* copy atomic positions */ + system->atoms[atom_cnt].x[0] = strtod( &s_x[0], &endptr ); + system->atoms[atom_cnt].x[1] = strtod( &s_y[0], &endptr ); + system->atoms[atom_cnt].x[2] = strtod( &s_z[0], &endptr ); + + + /* atom name and type */ + strcpy( system->atoms[atom_cnt].name, atom_name ); + Trim_Spaces( element ); + system->atoms[atom_cnt].type = + Get_Atom_Type( &(system->reaxprm), element ); + + /* fprintf( stderr, + "a:%3d(%1d) c:%10.5f%10.5f%10.5f q:%10.5f occ:%s temp:%s seg_id:%s element:%s\n", + atom_cnt, system->atoms[ atom_cnt ].type, + system->atoms[ atom_cnt ].x[0], + system->atoms[ atom_cnt ].x[1], system->atoms[ atom_cnt ].x[2], + system->atoms[ atom_cnt ].q, occupancy, temp_factor, + seg_id, element ); */ + + atom_cnt++; + } + else if (!strncmp( tokens[0], "CRYSTX", 6 )) + { + sscanf( backup, BGF_CRYSTX_FORMAT, + &descriptor[0], + &s_a[0], + &s_b[0], + &s_c[0], + &s_alpha[0], + &s_beta[0], + &s_gamma[0] ); + + /* Compute full volume tensor from the angles */ + Init_Box_From_CRYST( atof(s_a), atof(s_b), atof(s_c), + atof(s_alpha), atof(s_beta), atof(s_gamma), + &(system->box) ); + } + else if (!strncmp( tokens[0], "CONECT", 6 )) + { + /* check number of restrictions */ + Check_Input_Range( token_cnt - 2, 0, MAX_RESTRICT, + "CONECT line exceeds max restrictions allowed.\n" ); + + /* read bond restrictions */ + if ( is_Valid_Serial( workspace, bgf_serial = atoi(tokens[1]) ) ) + ratom = workspace->map_serials[ bgf_serial ]; + + workspace->restricted[ ratom ] = token_cnt - 2; + for ( i = 2; i < token_cnt; ++i ) + if ( is_Valid_Serial( workspace, bgf_serial = atoi(tokens[i]) ) ) + workspace->restricted_list[ ratom ][ i - 2 ] = + workspace->map_serials[ bgf_serial ]; + + /* fprintf( stderr, "restriction on %d:", ratom ); + for( i = 0; i < workspace->restricted[ ratom ]; ++i ) + fprintf( stderr, " %d", workspace->restricted_list[ratom][i] ); + fprintf( stderr, "\n" ); */ + } } - else if(!strncmp( tokens[0], "CONECT", 6 )) { - /* check number of restrictions */ - Check_Input_Range( token_cnt - 2, 0, MAX_RESTRICT, - "CONECT line exceeds max restrictions allowed.\n" ); - - /* read bond restrictions */ - if( is_Valid_Serial( workspace, bgf_serial = atoi(tokens[1]) ) ) - ratom = workspace->map_serials[ bgf_serial ]; - - workspace->restricted[ ratom ] = token_cnt - 2; - for( i = 2; i < token_cnt; ++i ) - if( is_Valid_Serial( workspace, bgf_serial = atoi(tokens[i]) ) ) - workspace->restricted_list[ ratom ][ i-2 ] = - workspace->map_serials[ bgf_serial ]; - - /* fprintf( stderr, "restriction on %d:", ratom ); - for( i = 0; i < workspace->restricted[ ratom ]; ++i ) - fprintf( stderr, " %d", workspace->restricted_list[ratom][i] ); - fprintf( stderr, "\n" ); */ - } - } - - fclose( bgf ); + + fclose( bgf ); #if defined(DEBUG_FOCUS) - fprintf( stderr, "bgf file read\n" ); + fprintf( stderr, "bgf file read\n" ); #endif - return 1; -} + return 1; +} diff --git a/puremd_rc_1003/sPuReMD/pdb_tools.h b/puremd_rc_1003/sPuReMD/pdb_tools.h index 212cf6a5..c3afab9f 100644 --- a/puremd_rc_1003/sPuReMD/pdb_tools.h +++ b/puremd_rc_1003/sPuReMD/pdb_tools.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -25,14 +25,14 @@ #include "mytypes.h" /* -PDB format : +PDB format : http://www.rcsb.org/pdb/file_formats/pdb/pdbguide2.2/guide2.2_frame.html #define PDB_ATOM_FORMAT "%6s%5d%4s%c%4s%c%4d%c%8s%8s%8s%6s%6s%4s%2s%2s\n" COLUMNS DATA TYPE FIELD DEFINITION -------------------------------------------------------------------------------- -1 - 6 Record name "ATOM " +1 - 6 Record name "ATOM " 7 - 11 Integer serial Atom serial number. 13 - 16 Atom name Atom name. 17 Character altLoc Alternate location indicator. @@ -43,7 +43,7 @@ COLUMNS DATA TYPE FIELD DEFINITION 31 - 38 Real(8.3) x Orthogonal coord for X in Angstroms 39 - 46 Real(8.3) y Orthogonal coord for Y in Angstroms 47 - 54 Real(8.3) z Orthogonal coord for Z in Angstroms -55 - 60 Real(6.2) occupancy Occupancy. +55 - 60 Real(6.2) occupancy Occupancy. 61 - 66 Real(6.2) tempFactor Temperature factor. 73 - 76 LString(4) segID Segment identifier, left-justified. 77 - 78 LString(2) element Element symbol, right-justified. @@ -82,9 +82,9 @@ COLUMNS DATA TYPE FIELD DEFINITION */ /* -COLUMNS DATA TYPE FIELD DEFINITION ----------------------------------------------------------- -1 - 6 Record name "CRYST1" +COLUMNS DATA TYPE FIELD DEFINITION +---------------------------------------------------------- +1 - 6 Record name "CRYST1" 7 - 15 Real(9.3) a a (Angstroms) 16 - 24 Real(9.3) b b (Angstroms) 25 - 33 Real(9.3) c c (Angstroms) @@ -107,12 +107,12 @@ COLUMNS DATA TYPE FIELD DEFINITION #define BGF_CRYSTX_FORMAT "%8s%11s%11s%11s%11s%11s%11s" -char Read_PDB( char*, reax_system*, control_params*, - simulation_data*, static_storage* ); -char Read_BGF( char*, reax_system*, control_params*, - simulation_data*, static_storage* ); +char Read_PDB( char*, reax_system*, control_params*, + simulation_data*, static_storage* ); +char Read_BGF( char*, reax_system*, control_params*, + simulation_data*, static_storage* ); -char Write_PDB( reax_system*, control_params*, simulation_data*, - static_storage*, list*, output_controls* ); +char Write_PDB( reax_system*, control_params*, simulation_data*, + static_storage*, list*, output_controls* ); #endif diff --git a/puremd_rc_1003/sPuReMD/print_utils.c b/puremd_rc_1003/sPuReMD/print_utils.c index 46127cd5..20d58e75 100644 --- a/puremd_rc_1003/sPuReMD/print_utils.c +++ b/puremd_rc_1003/sPuReMD/print_utils.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -27,843 +27,868 @@ #ifdef TEST_FORCES -void Dummy_Printer( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Dummy_Printer( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { } -void Print_Bond_Orders( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Print_Bond_Orders( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i, pj, pk; - bond_order_data *bo_ij; - list *bonds = (*lists) + BONDS; - list *dBOs = (*lists) + DBO; - dbond_data *dbo_k; - - - /* bond orders */ - fprintf( out_control->fbo, "%6s%6s%12s%12s%12s%12s%12s\n", - "atom1", "atom2", "r_ij", "total_bo", "bo_s", "bo_p", "bo_pp" ); - - for( i = 0; i < system->N; ++i ) - for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) { - bo_ij = &(bonds->select.bond_list[pj].bo_data); - fprintf( out_control->fbo, "%6d%6d%23.15e%23.15e%23.15e%23.15e%23.15e\n", - //workspace->orig_id[i], - //workspace->orig_id[bonds->select.bond_list[pj].nbr], - i+1, - bonds->select.bond_list[pj].nbr+1, - bonds->select.bond_list[pj].d, - bo_ij->BO, bo_ij->BO_s, bo_ij->BO_pi, bo_ij->BO_pi2 ); - } - - /* derivatives of bond orders */ - /* fprintf( out_control->fbo, "%6s%6s%10s%10s%10s%10s\n", - "atom1", "atom2", "total_bo", "bo_s", "bo_p", "bo_pp"\n ); */ - - for( i = 0; i < system->N; ++i ) - for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) { - /*fprintf( out_control->fdbo, "%6d %6d\tstart: %6d\tend: %6d\n", - workspace->orig_id[i], - workspace->orig_id[bonds->select.bond_list[pj].nbr], - Start_Index( pj, dBOs ), End_Index( pj, dBOs ) );*/ - - for( pk = Start_Index(pj,dBOs); pk < End_Index(pj,dBOs); ++pk ) { - dbo_k = &(dBOs->select.dbo_list[pk]); - - //if( !rvec_isZero( dbo_k->dBO ) ) - fprintf( out_control->fdbo, "%6d%6d%6d%23.15e%23.15e%23.15e\n", - workspace->orig_id[i], - workspace->orig_id[bonds->select.bond_list[pj].nbr], - workspace->orig_id[dbo_k->wrt], - dbo_k->dBO[0], dbo_k->dBO[1], dbo_k->dBO[2] ); - - fprintf( out_control->fdbo, "%6d%6d%6d%23.15e%23.15e%23.15e\n", - workspace->orig_id[i], - workspace->orig_id[bonds->select.bond_list[pj].nbr], - workspace->orig_id[dbo_k->wrt], - dbo_k->dBOpi[0], dbo_k->dBOpi[1], dbo_k->dBOpi[2] ); - - fprintf( out_control->fdbo, "%6d%6d%6d%23.15e%23.15e%23.15e\n", - workspace->orig_id[i], - workspace->orig_id[bonds->select.bond_list[pj].nbr], - workspace->orig_id[dbo_k->wrt], - dbo_k->dBOpi2[0], dbo_k->dBOpi2[1], dbo_k->dBOpi2[2] ); - } - } - - fflush(out_control->fdbo); + int i, pj, pk; + bond_order_data *bo_ij; + list *bonds = (*lists) + BONDS; + list *dBOs = (*lists) + DBO; + dbond_data *dbo_k; + + + /* bond orders */ + fprintf( out_control->fbo, "%6s%6s%12s%12s%12s%12s%12s\n", + "atom1", "atom2", "r_ij", "total_bo", "bo_s", "bo_p", "bo_pp" ); + + for ( i = 0; i < system->N; ++i ) + for ( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) + { + bo_ij = &(bonds->select.bond_list[pj].bo_data); + fprintf( out_control->fbo, "%6d%6d%23.15e%23.15e%23.15e%23.15e%23.15e\n", + //workspace->orig_id[i], + //workspace->orig_id[bonds->select.bond_list[pj].nbr], + i + 1, + bonds->select.bond_list[pj].nbr + 1, + bonds->select.bond_list[pj].d, + bo_ij->BO, bo_ij->BO_s, bo_ij->BO_pi, bo_ij->BO_pi2 ); + } + + /* derivatives of bond orders */ + /* fprintf( out_control->fbo, "%6s%6s%10s%10s%10s%10s\n", + "atom1", "atom2", "total_bo", "bo_s", "bo_p", "bo_pp"\n ); */ + + for ( i = 0; i < system->N; ++i ) + for ( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) + { + /*fprintf( out_control->fdbo, "%6d %6d\tstart: %6d\tend: %6d\n", + workspace->orig_id[i], + workspace->orig_id[bonds->select.bond_list[pj].nbr], + Start_Index( pj, dBOs ), End_Index( pj, dBOs ) );*/ + + for ( pk = Start_Index(pj, dBOs); pk < End_Index(pj, dBOs); ++pk ) + { + dbo_k = &(dBOs->select.dbo_list[pk]); + + //if( !rvec_isZero( dbo_k->dBO ) ) + fprintf( out_control->fdbo, "%6d%6d%6d%23.15e%23.15e%23.15e\n", + workspace->orig_id[i], + workspace->orig_id[bonds->select.bond_list[pj].nbr], + workspace->orig_id[dbo_k->wrt], + dbo_k->dBO[0], dbo_k->dBO[1], dbo_k->dBO[2] ); + + fprintf( out_control->fdbo, "%6d%6d%6d%23.15e%23.15e%23.15e\n", + workspace->orig_id[i], + workspace->orig_id[bonds->select.bond_list[pj].nbr], + workspace->orig_id[dbo_k->wrt], + dbo_k->dBOpi[0], dbo_k->dBOpi[1], dbo_k->dBOpi[2] ); + + fprintf( out_control->fdbo, "%6d%6d%6d%23.15e%23.15e%23.15e\n", + workspace->orig_id[i], + workspace->orig_id[bonds->select.bond_list[pj].nbr], + workspace->orig_id[dbo_k->wrt], + dbo_k->dBOpi2[0], dbo_k->dBOpi2[1], dbo_k->dBOpi2[2] ); + } + } + + fflush(out_control->fdbo); } -void Print_Bond_Forces( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Print_Bond_Forces( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i; + int i; - fprintf( out_control->fbond, "%d\n", data->step ); - fprintf( out_control->fbond, "%6s\t%s\n", "atom", "fbond" ); + fprintf( out_control->fbond, "%d\n", data->step ); + fprintf( out_control->fbond, "%6s\t%s\n", "atom", "fbond" ); - for( i = 0; i < system->N; ++i ) - fprintf(out_control->fbond, "%6d %23.15e%23.15e%23.15e\n", - workspace->orig_id[i], - workspace->f_be[i][0],workspace->f_be[i][1],workspace->f_be[i][2]); + for ( i = 0; i < system->N; ++i ) + fprintf(out_control->fbond, "%6d %23.15e%23.15e%23.15e\n", + workspace->orig_id[i], + workspace->f_be[i][0], workspace->f_be[i][1], workspace->f_be[i][2]); } -void Print_LonePair_Forces( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Print_LonePair_Forces( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i; + int i; - fprintf( out_control->flp, "%d\n", data->step ); - fprintf( out_control->flp, "%6s\t%s\n", "atom","f_lonepair" ); + fprintf( out_control->flp, "%d\n", data->step ); + fprintf( out_control->flp, "%6s\t%s\n", "atom", "f_lonepair" ); - for( i = 0; i < system->N; ++i ) - fprintf(out_control->flp, "%6d %23.15e%23.15e%23.15e\n", - workspace->orig_id[i], - workspace->f_lp[i][0],workspace->f_lp[i][1],workspace->f_lp[i][2]); + for ( i = 0; i < system->N; ++i ) + fprintf(out_control->flp, "%6d %23.15e%23.15e%23.15e\n", + workspace->orig_id[i], + workspace->f_lp[i][0], workspace->f_lp[i][1], workspace->f_lp[i][2]); - fflush(out_control->flp); + fflush(out_control->flp); } -void Print_OverUnderCoor_Forces( reax_system *system, control_params *control, - simulation_data *data, - static_storage *workspace, list **lists, - output_controls *out_control ) +void Print_OverUnderCoor_Forces( reax_system *system, control_params *control, + simulation_data *data, + static_storage *workspace, list **lists, + output_controls *out_control ) { - int i; - - fprintf( out_control->fatom, "%d\n", data->step ); - fprintf( out_control->fatom, "%6s\t%-38s%-38s%-38s\n", - "atom","f_atom", "f_over", "f_under" ); - - for( i = 0; i < system->N; ++i ){ - if( rvec_isZero( workspace->f_un[i] ) ) - fprintf( out_control->fatom, - "%6d %23.15e%23.15e%23.15e 0 0 0\n", - workspace->orig_id[i], workspace->f_ov[i][0], - workspace->f_ov[i][1], workspace->f_ov[i][2] ); - else - fprintf( out_control->fatom, - "%6d %23.15e%23.15e%23.15e %23.15e%23.15e%23.15e"\ - "%23.15e%23.15e%23.15e\n", - workspace->orig_id[i], - workspace->f_un[i][0] + workspace->f_ov[i][0], - workspace->f_un[i][1] + workspace->f_ov[i][1], - workspace->f_un[i][2] + workspace->f_ov[i][2], - workspace->f_ov[i][0], workspace->f_ov[i][1], - workspace->f_ov[i][2], - workspace->f_un[i][0], workspace->f_un[i][1], - workspace->f_un[i][2] ); - } - - fflush(out_control->fatom); + int i; + + fprintf( out_control->fatom, "%d\n", data->step ); + fprintf( out_control->fatom, "%6s\t%-38s%-38s%-38s\n", + "atom", "f_atom", "f_over", "f_under" ); + + for ( i = 0; i < system->N; ++i ) + { + if ( rvec_isZero( workspace->f_un[i] ) ) + fprintf( out_control->fatom, + "%6d %23.15e%23.15e%23.15e 0 0 0\n", + workspace->orig_id[i], workspace->f_ov[i][0], + workspace->f_ov[i][1], workspace->f_ov[i][2] ); + else + fprintf( out_control->fatom, + "%6d %23.15e%23.15e%23.15e %23.15e%23.15e%23.15e"\ + "%23.15e%23.15e%23.15e\n", + workspace->orig_id[i], + workspace->f_un[i][0] + workspace->f_ov[i][0], + workspace->f_un[i][1] + workspace->f_ov[i][1], + workspace->f_un[i][2] + workspace->f_ov[i][2], + workspace->f_ov[i][0], workspace->f_ov[i][1], + workspace->f_ov[i][2], + workspace->f_un[i][0], workspace->f_un[i][1], + workspace->f_un[i][2] ); + } + + fflush(out_control->fatom); } -void Print_Three_Body_Forces( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Print_Three_Body_Forces( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int j; - - fprintf( out_control->f3body, "%d\n", data->step ); - fprintf( out_control->f3body, "%6s%-37s%-37s%-37s%-38s\n", - "atom", "3-body total", "f_ang", "f_pen", "f_coa" ); - - for( j = 0; j < system->N; ++j ){ - if( rvec_isZero(workspace->f_pen[j]) && rvec_isZero(workspace->f_coa[j]) ) - fprintf( out_control->f3body, "%6d %23.15e%23.15e%23.15e 0 0 0 0 0 0\n", - workspace->orig_id[j], workspace->f_ang[j][0], - workspace->f_ang[j][1], workspace->f_ang[j][2] ); - else if( rvec_isZero(workspace->f_coa[j]) ) - fprintf( out_control->f3body, - "%6d %23.15e%23.15e%23.15e %23.15e%23.15e%23.15e "\ - "%23.15e%23.15e%23.15e\n", - workspace->orig_id[j], - workspace->f_ang[j][0] + workspace->f_pen[j][0], - workspace->f_ang[j][1] + workspace->f_pen[j][1], - workspace->f_ang[j][2] + workspace->f_pen[j][2], - workspace->f_ang[j][0], workspace->f_ang[j][1], - workspace->f_ang[j][2], - workspace->f_pen[j][0], workspace->f_pen[j][1], - workspace->f_pen[j][2] ); - else{ - fprintf( out_control->f3body, "%6d %23.15e%23.15e%23.15e ", - workspace->orig_id[j], - workspace->f_ang[j][0] + workspace->f_pen[j][0] + - workspace->f_coa[j][0], - workspace->f_ang[j][1] + workspace->f_pen[j][1] + - workspace->f_coa[j][1], - workspace->f_ang[j][2] + workspace->f_pen[j][2] + - workspace->f_coa[j][2] ); - - fprintf( out_control->f3body, - "%23.15e%23.15e%23.15e %23.15e%23.15e%23.15e "\ - "%23.15e%23.15e%23.15e\n", - workspace->f_ang[j][0], workspace->f_ang[j][1], - workspace->f_ang[j][2], - workspace->f_pen[j][0], workspace->f_pen[j][1], - workspace->f_pen[j][2], - workspace->f_coa[j][0], workspace->f_coa[j][1], - workspace->f_coa[j][2] ); + int j; + + fprintf( out_control->f3body, "%d\n", data->step ); + fprintf( out_control->f3body, "%6s%-37s%-37s%-37s%-38s\n", + "atom", "3-body total", "f_ang", "f_pen", "f_coa" ); + + for ( j = 0; j < system->N; ++j ) + { + if ( rvec_isZero(workspace->f_pen[j]) && rvec_isZero(workspace->f_coa[j]) ) + fprintf( out_control->f3body, "%6d %23.15e%23.15e%23.15e 0 0 0 0 0 0\n", + workspace->orig_id[j], workspace->f_ang[j][0], + workspace->f_ang[j][1], workspace->f_ang[j][2] ); + else if ( rvec_isZero(workspace->f_coa[j]) ) + fprintf( out_control->f3body, + "%6d %23.15e%23.15e%23.15e %23.15e%23.15e%23.15e "\ + "%23.15e%23.15e%23.15e\n", + workspace->orig_id[j], + workspace->f_ang[j][0] + workspace->f_pen[j][0], + workspace->f_ang[j][1] + workspace->f_pen[j][1], + workspace->f_ang[j][2] + workspace->f_pen[j][2], + workspace->f_ang[j][0], workspace->f_ang[j][1], + workspace->f_ang[j][2], + workspace->f_pen[j][0], workspace->f_pen[j][1], + workspace->f_pen[j][2] ); + else + { + fprintf( out_control->f3body, "%6d %23.15e%23.15e%23.15e ", + workspace->orig_id[j], + workspace->f_ang[j][0] + workspace->f_pen[j][0] + + workspace->f_coa[j][0], + workspace->f_ang[j][1] + workspace->f_pen[j][1] + + workspace->f_coa[j][1], + workspace->f_ang[j][2] + workspace->f_pen[j][2] + + workspace->f_coa[j][2] ); + + fprintf( out_control->f3body, + "%23.15e%23.15e%23.15e %23.15e%23.15e%23.15e "\ + "%23.15e%23.15e%23.15e\n", + workspace->f_ang[j][0], workspace->f_ang[j][1], + workspace->f_ang[j][2], + workspace->f_pen[j][0], workspace->f_pen[j][1], + workspace->f_pen[j][2], + workspace->f_coa[j][0], workspace->f_coa[j][1], + workspace->f_coa[j][2] ); + } } - } - fflush(out_control->f3body); + fflush(out_control->f3body); } -void Print_Hydrogen_Bond_Forces( reax_system *system, control_params *control, - simulation_data *data, - static_storage *workspace, list **lists, - output_controls *out_control ) +void Print_Hydrogen_Bond_Forces( reax_system *system, control_params *control, + simulation_data *data, + static_storage *workspace, list **lists, + output_controls *out_control ) { - int j; - - fprintf( out_control->fhb, "%d\n", data->step ); - fprintf( out_control->fhb, "%6s\t%-38s\n", "atom", "f_hb" ); - - for( j = 0; j < system->N; ++j ) - fprintf(out_control->fhb, "%6d\t[%23.15e%23.15e%23.15e]\n", - workspace->orig_id[j], - workspace->f_hb[j][0],workspace->f_hb[j][1],workspace->f_hb[j][2]); - - fflush(out_control->fhb); + int j; + + fprintf( out_control->fhb, "%d\n", data->step ); + fprintf( out_control->fhb, "%6s\t%-38s\n", "atom", "f_hb" ); + + for ( j = 0; j < system->N; ++j ) + fprintf(out_control->fhb, "%6d\t[%23.15e%23.15e%23.15e]\n", + workspace->orig_id[j], + workspace->f_hb[j][0], workspace->f_hb[j][1], workspace->f_hb[j][2]); + + fflush(out_control->fhb); } - -void Print_Four_Body_Forces( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) + +void Print_Four_Body_Forces( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int j; - - fprintf( out_control->f4body, "%6s\t%-38s%-38s%-38s\n", - "atom", "4-body total", "f_tor", "f_con" ); - - for( j = 0; j < system->N; ++j ){ - if( !rvec_isZero( workspace->f_con[j] ) ) - fprintf( out_control->f4body, - "%6d %23.15e%23.15e%23.15e %23.15e%23.15e%23.15e "\ - "%23.15e%23.15e%23.15e\n", - workspace->orig_id[j], - workspace->f_tor[j][0] + workspace->f_con[j][0], - workspace->f_tor[j][1] + workspace->f_con[j][1], - workspace->f_tor[j][2] + workspace->f_con[j][2], - workspace->f_tor[j][0], workspace->f_tor[j][1], - workspace->f_tor[j][2], - workspace->f_con[j][0], workspace->f_con[j][1], - workspace->f_con[j][2] ); - else - fprintf( out_control->f4body, - "%6d %23.15e%23.15e%23.15e 0 0 0\n", - workspace->orig_id[j], workspace->f_tor[j][0], - workspace->f_tor[j][1], workspace->f_tor[j][2] ); - } - - fflush(out_control->f4body); + int j; + + fprintf( out_control->f4body, "%6s\t%-38s%-38s%-38s\n", + "atom", "4-body total", "f_tor", "f_con" ); + + for ( j = 0; j < system->N; ++j ) + { + if ( !rvec_isZero( workspace->f_con[j] ) ) + fprintf( out_control->f4body, + "%6d %23.15e%23.15e%23.15e %23.15e%23.15e%23.15e "\ + "%23.15e%23.15e%23.15e\n", + workspace->orig_id[j], + workspace->f_tor[j][0] + workspace->f_con[j][0], + workspace->f_tor[j][1] + workspace->f_con[j][1], + workspace->f_tor[j][2] + workspace->f_con[j][2], + workspace->f_tor[j][0], workspace->f_tor[j][1], + workspace->f_tor[j][2], + workspace->f_con[j][0], workspace->f_con[j][1], + workspace->f_con[j][2] ); + else + fprintf( out_control->f4body, + "%6d %23.15e%23.15e%23.15e 0 0 0\n", + workspace->orig_id[j], workspace->f_tor[j][0], + workspace->f_tor[j][1], workspace->f_tor[j][2] ); + } + + fflush(out_control->f4body); } -void Print_vdW_Coulomb_Forces( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Print_vdW_Coulomb_Forces( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i; - - fprintf( out_control->fnonb, "%d\n", data->step ); - fprintf( out_control->fnonb, "%6s\t%-38s%-38s%-38s\n", - "atom", "nonbonded total", "f_vdw", "f_ele" ); - - for( i = 0; i < system->N; ++i ) - if( !rvec_isZero(workspace->f_ele[i]) ) - fprintf(out_control->fnonb, - "%6d %23.15e%23.15e%23.15e %23.15e%23.15e%23.15e "\ - "%23.15e%23.15e%23.15e\n", - workspace->orig_id[i], - workspace->f_vdw[i][0] + workspace->f_ele[i][0], - workspace->f_vdw[i][1] + workspace->f_ele[i][1], - workspace->f_vdw[i][2] + workspace->f_ele[i][2], - workspace->f_vdw[i][0], workspace->f_vdw[i][1], - workspace->f_vdw[i][2], - workspace->f_ele[i][0], workspace->f_ele[i][1], - workspace->f_ele[i][2] ); - else - fprintf(out_control->fnonb, - "%6d %23.15e%23.15e%23.15e 0 0 0\n", - workspace->orig_id[i], workspace->f_vdw[i][0], - workspace->f_vdw[i][1], workspace->f_vdw[i][2] ); - - fflush(out_control->fnonb); + int i; + + fprintf( out_control->fnonb, "%d\n", data->step ); + fprintf( out_control->fnonb, "%6s\t%-38s%-38s%-38s\n", + "atom", "nonbonded total", "f_vdw", "f_ele" ); + + for ( i = 0; i < system->N; ++i ) + if ( !rvec_isZero(workspace->f_ele[i]) ) + fprintf(out_control->fnonb, + "%6d %23.15e%23.15e%23.15e %23.15e%23.15e%23.15e "\ + "%23.15e%23.15e%23.15e\n", + workspace->orig_id[i], + workspace->f_vdw[i][0] + workspace->f_ele[i][0], + workspace->f_vdw[i][1] + workspace->f_ele[i][1], + workspace->f_vdw[i][2] + workspace->f_ele[i][2], + workspace->f_vdw[i][0], workspace->f_vdw[i][1], + workspace->f_vdw[i][2], + workspace->f_ele[i][0], workspace->f_ele[i][1], + workspace->f_ele[i][2] ); + else + fprintf(out_control->fnonb, + "%6d %23.15e%23.15e%23.15e 0 0 0\n", + workspace->orig_id[i], workspace->f_vdw[i][0], + workspace->f_vdw[i][1], workspace->f_vdw[i][2] ); + + fflush(out_control->fnonb); } -void Compare_Total_Forces( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Compare_Total_Forces( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i; - - fprintf( out_control->ftot2, "%d\n", data->step ); - fprintf( out_control->ftot2, "%6s\t%-38s%-38s\n", - "atom", "f_total", "test_force total" ); - - for( i = 0; i < system->N; ++i ) - fprintf( out_control->ftot2, - "%6d %23.15e%23.15e%23.15e vs %23.15e%23.15e%23.15e\n", - workspace->orig_id[i], - system->atoms[i].f[0],system->atoms[i].f[1],system->atoms[i].f[2], - workspace->f_be[i][0]+ - workspace->f_lp[i][0]+workspace->f_ov[i][0]+workspace->f_un[i][0]+ - workspace->f_ang[i][0]+workspace->f_pen[i][0]+ - workspace->f_coa[i][0]+workspace->f_hb[i][0]+ - workspace->f_tor[i][0]+workspace->f_con[i][0]+ - workspace->f_vdw[i][0]+workspace->f_ele[i][0], - workspace->f_be[i][1]+ - workspace->f_lp[i][1]+workspace->f_ov[i][1]+workspace->f_un[i][1]+ - workspace->f_ang[i][1]+workspace->f_pen[i][1]+ - workspace->f_coa[i][1]+workspace->f_hb[i][1]+ - workspace->f_tor[i][1]+workspace->f_con[i][1]+ - workspace->f_vdw[i][1]+workspace->f_ele[i][1], - workspace->f_be[i][2]+ - workspace->f_lp[i][2]+workspace->f_ov[i][2]+workspace->f_un[i][2]+ - workspace->f_ang[i][2]+workspace->f_pen[i][2]+ - workspace->f_coa[i][2]+workspace->f_hb[i][2]+ - workspace->f_tor[i][2]+workspace->f_con[i][2]+ - workspace->f_vdw[i][2]+workspace->f_ele[i][2] ); - - fflush(out_control->ftot2); + int i; + + fprintf( out_control->ftot2, "%d\n", data->step ); + fprintf( out_control->ftot2, "%6s\t%-38s%-38s\n", + "atom", "f_total", "test_force total" ); + + for ( i = 0; i < system->N; ++i ) + fprintf( out_control->ftot2, + "%6d %23.15e%23.15e%23.15e vs %23.15e%23.15e%23.15e\n", + workspace->orig_id[i], + system->atoms[i].f[0], system->atoms[i].f[1], system->atoms[i].f[2], + workspace->f_be[i][0] + + workspace->f_lp[i][0] + workspace->f_ov[i][0] + workspace->f_un[i][0] + + workspace->f_ang[i][0] + workspace->f_pen[i][0] + + workspace->f_coa[i][0] + workspace->f_hb[i][0] + + workspace->f_tor[i][0] + workspace->f_con[i][0] + + workspace->f_vdw[i][0] + workspace->f_ele[i][0], + workspace->f_be[i][1] + + workspace->f_lp[i][1] + workspace->f_ov[i][1] + workspace->f_un[i][1] + + workspace->f_ang[i][1] + workspace->f_pen[i][1] + + workspace->f_coa[i][1] + workspace->f_hb[i][1] + + workspace->f_tor[i][1] + workspace->f_con[i][1] + + workspace->f_vdw[i][1] + workspace->f_ele[i][1], + workspace->f_be[i][2] + + workspace->f_lp[i][2] + workspace->f_ov[i][2] + workspace->f_un[i][2] + + workspace->f_ang[i][2] + workspace->f_pen[i][2] + + workspace->f_coa[i][2] + workspace->f_hb[i][2] + + workspace->f_tor[i][2] + workspace->f_con[i][2] + + workspace->f_vdw[i][2] + workspace->f_ele[i][2] ); + + fflush(out_control->ftot2); } void Init_Force_Test_Functions( ) { - Print_Interactions[0] = Print_Bond_Orders; - Print_Interactions[1] = Print_Bond_Forces; - Print_Interactions[2] = Print_LonePair_Forces; - Print_Interactions[3] = Print_OverUnderCoor_Forces; - Print_Interactions[4] = Print_Three_Body_Forces; - Print_Interactions[5] = Print_Four_Body_Forces; - Print_Interactions[6] = Print_Hydrogen_Bond_Forces; - Print_Interactions[7] = Dummy_Printer; - Print_Interactions[8] = Dummy_Printer; - Print_Interactions[9] = Dummy_Printer; + Print_Interactions[0] = Print_Bond_Orders; + Print_Interactions[1] = Print_Bond_Forces; + Print_Interactions[2] = Print_LonePair_Forces; + Print_Interactions[3] = Print_OverUnderCoor_Forces; + Print_Interactions[4] = Print_Three_Body_Forces; + Print_Interactions[5] = Print_Four_Body_Forces; + Print_Interactions[6] = Print_Hydrogen_Bond_Forces; + Print_Interactions[7] = Dummy_Printer; + Print_Interactions[8] = Dummy_Printer; + Print_Interactions[9] = Dummy_Printer; } #endif char *Get_Element( reax_system *system, int i ) { - return &( system->reaxprm.sbp[system->atoms[i].type].name[0] ); + return &( system->reaxprm.sbp[system->atoms[i].type].name[0] ); } char *Get_Atom_Name( reax_system *system, int i ) { - return &(system->atoms[i].name[0]); + return &(system->atoms[i].name[0]); } /* near nbrs contain both i-j, j-i nbrhood info */ -void Print_Near_Neighbors( reax_system *system, control_params *control, - static_storage *workspace, list **lists ) +void Print_Near_Neighbors( reax_system *system, control_params *control, + static_storage *workspace, list **lists ) { - int i, j, id_i, id_j; - char fname[MAX_STR]; - FILE *fout; - list *near_nbrs = &((*lists)[NEAR_NBRS]); - - sprintf( fname, "%s.near_nbrs", control->sim_name ); - fout = fopen( fname, "w" ); - - fprintf( fout, "hello:!\n" ); - - for( i = 0; i < system->N; ++i ) { - id_i = workspace->orig_id[i]; - - for( j = Start_Index(i,near_nbrs); j < End_Index(i,near_nbrs); ++j ) { - id_j = workspace->orig_id[near_nbrs->select.near_nbr_list[j].nbr]; - - // if( id_i < id_j ) - fprintf( fout, "%6d%6d%23.15e%23.15e%23.15e%23.15e\n", - id_i, id_j, - near_nbrs->select.near_nbr_list[j].d, - near_nbrs->select.near_nbr_list[j].dvec[0], - near_nbrs->select.near_nbr_list[j].dvec[1], - near_nbrs->select.near_nbr_list[j].dvec[2] ); + int i, j, id_i, id_j; + char fname[MAX_STR]; + FILE *fout; + list *near_nbrs = &((*lists)[NEAR_NBRS]); + + sprintf( fname, "%s.near_nbrs", control->sim_name ); + fout = fopen( fname, "w" ); + + fprintf( fout, "hello:!\n" ); + + for ( i = 0; i < system->N; ++i ) + { + id_i = workspace->orig_id[i]; + + for ( j = Start_Index(i, near_nbrs); j < End_Index(i, near_nbrs); ++j ) + { + id_j = workspace->orig_id[near_nbrs->select.near_nbr_list[j].nbr]; + + // if( id_i < id_j ) + fprintf( fout, "%6d%6d%23.15e%23.15e%23.15e%23.15e\n", + id_i, id_j, + near_nbrs->select.near_nbr_list[j].d, + near_nbrs->select.near_nbr_list[j].dvec[0], + near_nbrs->select.near_nbr_list[j].dvec[1], + near_nbrs->select.near_nbr_list[j].dvec[2] ); + } } - } - - fclose( fout ); + + fclose( fout ); } /* near nbrs contain both i-j, j-i nbrhood info */ -void Print_Near_Neighbors2( reax_system *system, control_params *control, - static_storage *workspace, list **lists ) +void Print_Near_Neighbors2( reax_system *system, control_params *control, + static_storage *workspace, list **lists ) { - int i, j, id_i, id_j; - char fname[MAX_STR]; - FILE *fout; - list *near_nbrs = &((*lists)[NEAR_NBRS]); - - sprintf( fname, "%s.near_nbrs_lgj", control->sim_name ); - fout = fopen( fname, "w" ); - - for( i = 0; i < system->N; ++i ) { - id_i = workspace->orig_id[i]; - fprintf( fout, "%6d:",id_i); - for( j = Start_Index(i,near_nbrs); j < End_Index(i,near_nbrs); ++j ) { - id_j = workspace->orig_id[near_nbrs->select.near_nbr_list[j].nbr]; - fprintf( fout, "%6d", id_j); - - /* fprintf( fout, "%6d%6d%23.15e%23.15e%23.15e%23.15e\n", - id_i, id_j, - near_nbrs->select.near_nbr_list[j].d, - near_nbrs->select.near_nbr_list[j].dvec[0], - near_nbrs->select.near_nbr_list[j].dvec[1], - near_nbrs->select.near_nbr_list[j].dvec[2] ); */ + int i, j, id_i, id_j; + char fname[MAX_STR]; + FILE *fout; + list *near_nbrs = &((*lists)[NEAR_NBRS]); + + sprintf( fname, "%s.near_nbrs_lgj", control->sim_name ); + fout = fopen( fname, "w" ); + + for ( i = 0; i < system->N; ++i ) + { + id_i = workspace->orig_id[i]; + fprintf( fout, "%6d:", id_i); + for ( j = Start_Index(i, near_nbrs); j < End_Index(i, near_nbrs); ++j ) + { + id_j = workspace->orig_id[near_nbrs->select.near_nbr_list[j].nbr]; + fprintf( fout, "%6d", id_j); + + /* fprintf( fout, "%6d%6d%23.15e%23.15e%23.15e%23.15e\n", + id_i, id_j, + near_nbrs->select.near_nbr_list[j].d, + near_nbrs->select.near_nbr_list[j].dvec[0], + near_nbrs->select.near_nbr_list[j].dvec[1], + near_nbrs->select.near_nbr_list[j].dvec[2] ); */ + } + fprintf( fout, "\n"); } - fprintf( fout, "\n"); - } - - fclose( fout ); + + fclose( fout ); } /* far nbrs contain only i-j nbrhood info, no j-i. */ -void Print_Far_Neighbors( reax_system *system, control_params *control, - static_storage *workspace, list **lists ) +void Print_Far_Neighbors( reax_system *system, control_params *control, + static_storage *workspace, list **lists ) { - int i, j, id_i, id_j; - char fname[MAX_STR]; - FILE *fout; - list *far_nbrs = &((*lists)[FAR_NBRS]); - - sprintf( fname, "%s.far_nbrs", control->sim_name ); - fout = fopen( fname, "w" ); - - for( i = 0; i < system->N; ++i ) { - id_i = workspace->orig_id[i]; - - for( j = Start_Index(i, far_nbrs); j < End_Index(i, far_nbrs); ++j ) { - id_j = workspace->orig_id[far_nbrs->select.far_nbr_list[j].nbr]; - - fprintf( fout, "%6d%6d%23.15e%23.15e%23.15e%23.15e\n", - id_i, id_j, - far_nbrs->select.far_nbr_list[j].d, - far_nbrs->select.far_nbr_list[j].dvec[0], - far_nbrs->select.far_nbr_list[j].dvec[1], - far_nbrs->select.far_nbr_list[j].dvec[2] ); - - fprintf( fout, "%6d%6d%23.15e%23.15e%23.15e%23.15e\n", - id_j, id_i, - far_nbrs->select.far_nbr_list[j].d, - -far_nbrs->select.far_nbr_list[j].dvec[0], - -far_nbrs->select.far_nbr_list[j].dvec[1], - -far_nbrs->select.far_nbr_list[j].dvec[2] ); + int i, j, id_i, id_j; + char fname[MAX_STR]; + FILE *fout; + list *far_nbrs = &((*lists)[FAR_NBRS]); + + sprintf( fname, "%s.far_nbrs", control->sim_name ); + fout = fopen( fname, "w" ); + + for ( i = 0; i < system->N; ++i ) + { + id_i = workspace->orig_id[i]; + + for ( j = Start_Index(i, far_nbrs); j < End_Index(i, far_nbrs); ++j ) + { + id_j = workspace->orig_id[far_nbrs->select.far_nbr_list[j].nbr]; + + fprintf( fout, "%6d%6d%23.15e%23.15e%23.15e%23.15e\n", + id_i, id_j, + far_nbrs->select.far_nbr_list[j].d, + far_nbrs->select.far_nbr_list[j].dvec[0], + far_nbrs->select.far_nbr_list[j].dvec[1], + far_nbrs->select.far_nbr_list[j].dvec[2] ); + + fprintf( fout, "%6d%6d%23.15e%23.15e%23.15e%23.15e\n", + id_j, id_i, + far_nbrs->select.far_nbr_list[j].d, + -far_nbrs->select.far_nbr_list[j].dvec[0], + -far_nbrs->select.far_nbr_list[j].dvec[1], + -far_nbrs->select.far_nbr_list[j].dvec[2] ); + } } - } - - fclose( fout ); + + fclose( fout ); } -int fn_qsort_intcmp( const void *a, const void *b ) -{ - return( *(int *)a - *(int *)b); -} +int fn_qsort_intcmp( const void *a, const void *b ) +{ + return ( *(int *)a - * (int *)b); +} -void Print_Far_Neighbors2( reax_system *system, control_params *control, - static_storage *workspace, list **lists ) +void Print_Far_Neighbors2( reax_system *system, control_params *control, + static_storage *workspace, list **lists ) { - int i, j, id_i, id_j; - char fname[MAX_STR]; - FILE *fout; - list *far_nbrs = &((*lists)[FAR_NBRS]); - - sprintf( fname, "%s.far_nbrs_lgj", control->sim_name ); - fout = fopen( fname, "w" ); - int num=0; - int temp[500]; - - for( i = 0; i < system->N; ++i ) { - id_i = workspace->orig_id[i]; - num=0; - fprintf( fout, "%6d:",id_i); - - for( j = Start_Index(i, far_nbrs); j < End_Index(i, far_nbrs); ++j ) { - id_j = workspace->orig_id[far_nbrs->select.far_nbr_list[j].nbr]; - temp[num++] = id_j; + int i, j, id_i, id_j; + char fname[MAX_STR]; + FILE *fout; + list *far_nbrs = &((*lists)[FAR_NBRS]); + + sprintf( fname, "%s.far_nbrs_lgj", control->sim_name ); + fout = fopen( fname, "w" ); + int num = 0; + int temp[500]; + + for ( i = 0; i < system->N; ++i ) + { + id_i = workspace->orig_id[i]; + num = 0; + fprintf( fout, "%6d:", id_i); + + for ( j = Start_Index(i, far_nbrs); j < End_Index(i, far_nbrs); ++j ) + { + id_j = workspace->orig_id[far_nbrs->select.far_nbr_list[j].nbr]; + temp[num++] = id_j; + } + qsort(&temp, num, sizeof(int), fn_qsort_intcmp); + for (j = 0; j < num; j++) + fprintf(fout, "%6d", temp[j]); + fprintf( fout, "\n"); } - qsort(&temp, num, sizeof(int), fn_qsort_intcmp); - for(j=0; j < num; j++) - fprintf(fout, "%6d",temp[j]); - fprintf( fout, "\n"); - } - fclose( fout ); + fclose( fout ); } -void Print_Total_Force( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Print_Total_Force( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i; + int i; #if !defined(TEST_FORCES) - char temp[1000]; - sprintf( temp, "%s.ftot", control->sim_name ); - out_control->ftot = fopen( temp, "w" ); + char temp[1000]; + sprintf( temp, "%s.ftot", control->sim_name ); + out_control->ftot = fopen( temp, "w" ); #endif - for( i = 0; i < system->N; ++i ) - fprintf(out_control->ftot, "%6d %23.15e %23.15e %23.15e\n", - //fprintf(out_control->ftot, "%6d %19.9e %19.9e %19.9e\n", - //fprintf(out_control->ftot, "%3d %12.6f %12.6f %12.6f\n", - workspace->orig_id[i], - system->atoms[i].f[0],system->atoms[i].f[1],system->atoms[i].f[2]); + for ( i = 0; i < system->N; ++i ) + fprintf(out_control->ftot, "%6d %23.15e %23.15e %23.15e\n", + //fprintf(out_control->ftot, "%6d %19.9e %19.9e %19.9e\n", + //fprintf(out_control->ftot, "%3d %12.6f %12.6f %12.6f\n", + workspace->orig_id[i], + system->atoms[i].f[0], system->atoms[i].f[1], system->atoms[i].f[2]); - fflush(out_control->ftot); + fflush(out_control->ftot); #if !defined(TEST_FORCES) - fclose(out_control->ftot); + fclose(out_control->ftot); #endif } -void Output_Results( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Output_Results( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i, type_i, f_update; - real q; - real t_elapsed = 0;; - - - /* Compute Polarization Energy */ - data->E_Pol = 0.0; - for( i = 0; i < system->N; i++ ) { - q = system->atoms[i].q; - type_i = system->atoms[i].type; - - data->E_Pol += ( system->reaxprm.sbp[ type_i ].chi * q + - (system->reaxprm.sbp[ type_i ].eta / 2.0) * SQR(q) ) * - KCALpMOL_to_EV; - /* fprintf( stderr, "%6d%23.15e%23.15e%23.15e%23.15e\n", - i, q, system->reaxprm.sbp[ type_i ].chi, - system->reaxprm.sbp[ type_i ].eta, data->E_Pol ); */ - } - - data->E_Pot = data->E_BE + data->E_Ov + data->E_Un + data->E_Lp + - data->E_Ang + data->E_Pen + data->E_Coa + data->E_HB + - data->E_Tor + data->E_Con + - data->E_vdW + data->E_Ele + data->E_Pol; - - data->E_Tot = data->E_Pot + E_CONV*data->E_Kin; - - - /* output energies if it is the time */ - if( out_control->energy_update_freq > 0 && - data->step % out_control->energy_update_freq == 0 ) { + int i, type_i, f_update; + real q; + real t_elapsed = 0;; + + + /* Compute Polarization Energy */ + data->E_Pol = 0.0; + for ( i = 0; i < system->N; i++ ) + { + q = system->atoms[i].q; + type_i = system->atoms[i].type; + + data->E_Pol += ( system->reaxprm.sbp[ type_i ].chi * q + + (system->reaxprm.sbp[ type_i ].eta / 2.0) * SQR(q) ) * + KCALpMOL_to_EV; + /* fprintf( stderr, "%6d%23.15e%23.15e%23.15e%23.15e\n", + i, q, system->reaxprm.sbp[ type_i ].chi, + system->reaxprm.sbp[ type_i ].eta, data->E_Pol ); */ + } + + data->E_Pot = data->E_BE + data->E_Ov + data->E_Un + data->E_Lp + + data->E_Ang + data->E_Pen + data->E_Coa + data->E_HB + + data->E_Tor + data->E_Con + + data->E_vdW + data->E_Ele + data->E_Pol; + + data->E_Tot = data->E_Pot + E_CONV * data->E_Kin; + + + /* output energies if it is the time */ + if ( out_control->energy_update_freq > 0 && + data->step % out_control->energy_update_freq == 0 ) + { #if defined(TEST_ENERGY) || defined(DEBUG) || defined(DEBUG_FOCUS) - fprintf( out_control->out, - "%-6d%24.15e%24.15e%24.15e%13.5f%13.5f%16.5f%13.5f%13.5f\n", - data->step, data->E_Tot, data->E_Pot, E_CONV*data->E_Kin, - data->therm.T, control->T, system->box.volume, data->iso_bar.P, - (control->P[0] + control->P[1] + control->P[2])/3 ); - - fprintf( out_control->pot, - "%-6d%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e\n", - data->step, - data->E_BE, - data->E_Ov + data->E_Un, data->E_Lp, - data->E_Ang+data->E_Pen, data->E_Coa, data->E_HB, - data->E_Tor, data->E_Con, - data->E_vdW, data->E_Ele, data->E_Pol ); + fprintf( out_control->out, + "%-6d%24.15e%24.15e%24.15e%13.5f%13.5f%16.5f%13.5f%13.5f\n", + data->step, data->E_Tot, data->E_Pot, E_CONV * data->E_Kin, + data->therm.T, control->T, system->box.volume, data->iso_bar.P, + (control->P[0] + control->P[1] + control->P[2]) / 3 ); + + fprintf( out_control->pot, + "%-6d%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e\n", + data->step, + data->E_BE, + data->E_Ov + data->E_Un, data->E_Lp, + data->E_Ang + data->E_Pen, data->E_Coa, data->E_HB, + data->E_Tor, data->E_Con, + data->E_vdW, data->E_Ele, data->E_Pol ); #else - fprintf( out_control->out, - "%-6d%16.2f%16.2f%16.2f%11.2f%11.2f%13.2f%13.5f%13.5f\n", - data->step, data->E_Tot, data->E_Pot, E_CONV*data->E_Kin, - data->therm.T, control->T, system->box.volume, data->iso_bar.P, - (control->P[0] + control->P[1] + control->P[2])/3 ); - - fprintf( out_control->pot, - "%-6d%13.2f%13.2f%13.2f%13.2f%13.2f%13.2f%13.2f%13.2f%13.2f%13.2f%13.2f\n", - data->step, - data->E_BE, - data->E_Ov + data->E_Un, data->E_Lp, - data->E_Ang + data->E_Pen, data->E_Coa, data->E_HB, - data->E_Tor, data->E_Con, - data->E_vdW, data->E_Ele, data->E_Pol ); + fprintf( out_control->out, + "%-6d%16.2f%16.2f%16.2f%11.2f%11.2f%13.2f%13.5f%13.5f\n", + data->step, data->E_Tot, data->E_Pot, E_CONV * data->E_Kin, + data->therm.T, control->T, system->box.volume, data->iso_bar.P, + (control->P[0] + control->P[1] + control->P[2]) / 3 ); + + fprintf( out_control->pot, + "%-6d%13.2f%13.2f%13.2f%13.2f%13.2f%13.2f%13.2f%13.2f%13.2f%13.2f%13.2f\n", + data->step, + data->E_BE, + data->E_Ov + data->E_Un, data->E_Lp, + data->E_Ang + data->E_Pen, data->E_Coa, data->E_HB, + data->E_Tor, data->E_Con, + data->E_vdW, data->E_Ele, data->E_Pol ); #endif - - t_elapsed = Get_Timing_Info( data->timing.total ); - if( data->step == data->prev_steps ) - f_update = 1; - else f_update = out_control->energy_update_freq; - - fprintf( out_control->log,"%6d%10.2f%10.2f%10.2f%10.2f%10.2f%10.2f%10.2f\n", - data->step, t_elapsed/f_update, - data->timing.nbrs/f_update, - data->timing.init_forces/f_update, - data->timing.bonded/f_update, - data->timing.nonb/f_update, - data->timing.QEq/f_update, - (double)data->timing.matvecs/f_update ); - - data->timing.total = Get_Time( ); - data->timing.nbrs = 0; - data->timing.init_forces = 0; - data->timing.bonded = 0; - data->timing.nonb = 0; - data->timing.QEq = 0; - data->timing.matvecs = 0; - - fflush( out_control->out ); - fflush( out_control->pot ); - fflush( out_control->log ); - - /* output pressure */ - if( control->ensemble == NPT || control->ensemble == iNPT || - control->ensemble == sNPT ) { - fprintf( out_control->prs, "%-8d%13.6f%13.6f%13.6f", - data->step, - data->int_press[0], data->int_press[1], data->int_press[2] ); - - /* external pressure is calculated together with forces */ - fprintf( out_control->prs, "%13.6f%13.6f%13.6f", - data->ext_press[0], data->ext_press[1], data->ext_press[2] ); - - fprintf( out_control->prs, "%13.6f\n", data->kin_press ); - - fprintf( out_control->prs, - "%-8d%13.6f%13.6f%13.6f%13.6f%13.6f%13.6f%13.6f%13.6f%13.6f%13.6f\n", - data->step, - system->box.box_norms[0], system->box.box_norms[1], - system->box.box_norms[2], - data->tot_press[0], data->tot_press[1], data->tot_press[2], - control->P[0],control->P[1],control->P[2],system->box.volume ); - fflush( out_control->prs); + + t_elapsed = Get_Timing_Info( data->timing.total ); + if ( data->step == data->prev_steps ) + f_update = 1; + else f_update = out_control->energy_update_freq; + + fprintf( out_control->log, "%6d%10.2f%10.2f%10.2f%10.2f%10.2f%10.2f%10.2f\n", + data->step, t_elapsed / f_update, + data->timing.nbrs / f_update, + data->timing.init_forces / f_update, + data->timing.bonded / f_update, + data->timing.nonb / f_update, + data->timing.QEq / f_update, + (double)data->timing.matvecs / f_update ); + + data->timing.total = Get_Time( ); + data->timing.nbrs = 0; + data->timing.init_forces = 0; + data->timing.bonded = 0; + data->timing.nonb = 0; + data->timing.QEq = 0; + data->timing.matvecs = 0; + + fflush( out_control->out ); + fflush( out_control->pot ); + fflush( out_control->log ); + + /* output pressure */ + if ( control->ensemble == NPT || control->ensemble == iNPT || + control->ensemble == sNPT ) + { + fprintf( out_control->prs, "%-8d%13.6f%13.6f%13.6f", + data->step, + data->int_press[0], data->int_press[1], data->int_press[2] ); + + /* external pressure is calculated together with forces */ + fprintf( out_control->prs, "%13.6f%13.6f%13.6f", + data->ext_press[0], data->ext_press[1], data->ext_press[2] ); + + fprintf( out_control->prs, "%13.6f\n", data->kin_press ); + + fprintf( out_control->prs, + "%-8d%13.6f%13.6f%13.6f%13.6f%13.6f%13.6f%13.6f%13.6f%13.6f%13.6f\n", + data->step, + system->box.box_norms[0], system->box.box_norms[1], + system->box.box_norms[2], + data->tot_press[0], data->tot_press[1], data->tot_press[2], + control->P[0], control->P[1], control->P[2], system->box.volume ); + fflush( out_control->prs); + } + } + + if ( out_control->write_steps > 0 && + data->step % out_control->write_steps == 0 ) + { + // t_start = Get_Time( ); + out_control->append_traj_frame( system, control, data, + workspace, lists, out_control ); + + //Write_PDB( system, control, data, workspace, *lists+BONDS, out_control ); + // t_elapsed = Get_Timing_Info( t_start ); + // fprintf(stdout, "append_frame took %.6f seconds\n", t_elapsed ); } - } - - if( out_control->write_steps > 0 && - data->step % out_control->write_steps == 0 ){ - // t_start = Get_Time( ); - out_control->append_traj_frame( system, control, data, - workspace, lists, out_control ); - - //Write_PDB( system, control, data, workspace, *lists+BONDS, out_control ); - // t_elapsed = Get_Timing_Info( t_start ); - // fprintf(stdout, "append_frame took %.6f seconds\n", t_elapsed ); - } - - // fprintf( stderr, "output_results... done\n" ); + + // fprintf( stderr, "output_results... done\n" ); } -void Print_Linear_System( reax_system *system, control_params *control, - static_storage *workspace, int step ) +void Print_Linear_System( reax_system *system, control_params *control, + static_storage *workspace, int step ) { - int i, j; - char fname[100]; - sparse_matrix *H; - FILE *out; - - sprintf( fname, "%s.state%d.out", control->sim_name, step ); - out = fopen( fname, "w" ); - - for( i = 0; i < system->N; i++ ) - fprintf( out, "%6d%2d%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e\n", - workspace->orig_id[i],system->atoms[i].type, - system->atoms[i].x[0], system->atoms[i].x[1], - system->atoms[i].x[2], - workspace->s[0][i], workspace->b_s[i], - workspace->t[0][i], workspace->b_t[i] ); - fclose( out ); - - // sprintf( fname, "x2_%d", step ); - // out = fopen( fname, "w" ); - // for( i = 0; i < system->N; i++ ) - // fprintf( out, "%g\n", workspace->s_t[i+system->N] ); - // fclose( out ); - - - sprintf( fname, "%s.H%d.out", control->sim_name, step ); - out = fopen( fname, "w" ); - H = workspace->H; - - for( i = 0; i < system->N; ++i ) { - for( j = H->start[i]; j < H->start[i+1]-1; ++j ) { - fprintf( out, "%6d%6d %24.15e\n", - workspace->orig_id[i], workspace->orig_id[H->entries[j].j], - H->entries[j].val ); - - fprintf( out, "%6d%6d %24.15e\n", - workspace->orig_id[H->entries[j].j], workspace->orig_id[i], - H->entries[j].val ); - } - // the diagonal entry - fprintf( out, "%6d%6d %24.15e\n", - workspace->orig_id[i], workspace->orig_id[i], H->entries[j].val ); - } - - fclose( out ); - - /*sprintf( fname, "%s.b_s%d", control->sim_name, step ); + int i, j; + char fname[100]; + sparse_matrix *H; + FILE *out; + + sprintf( fname, "%s.state%d.out", control->sim_name, step ); out = fopen( fname, "w" ); - for( i = 0; i < system->N; i++ ) - fprintf( out, "%12.7f\n", workspace->b_s[i] ); + + for ( i = 0; i < system->N; i++ ) + fprintf( out, "%6d%2d%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e%24.15e\n", + workspace->orig_id[i], system->atoms[i].type, + system->atoms[i].x[0], system->atoms[i].x[1], + system->atoms[i].x[2], + workspace->s[0][i], workspace->b_s[i], + workspace->t[0][i], workspace->b_t[i] ); fclose( out ); - - sprintf( fname, "%s.b_t%d", control->sim_name, step ); + + // sprintf( fname, "x2_%d", step ); + // out = fopen( fname, "w" ); + // for( i = 0; i < system->N; i++ ) + // fprintf( out, "%g\n", workspace->s_t[i+system->N] ); + // fclose( out ); + + + sprintf( fname, "%s.H%d.out", control->sim_name, step ); out = fopen( fname, "w" ); - for( i = 0; i < system->N; i++ ) - fprintf( out, "%12.7f\n", workspace->b_t[i] ); - fclose( out );*/ + H = workspace->H; + + for ( i = 0; i < system->N; ++i ) + { + for ( j = H->start[i]; j < H->start[i + 1] - 1; ++j ) + { + fprintf( out, "%6d%6d %24.15e\n", + workspace->orig_id[i], workspace->orig_id[H->entries[j].j], + H->entries[j].val ); + + fprintf( out, "%6d%6d %24.15e\n", + workspace->orig_id[H->entries[j].j], workspace->orig_id[i], + H->entries[j].val ); + } + // the diagonal entry + fprintf( out, "%6d%6d %24.15e\n", + workspace->orig_id[i], workspace->orig_id[i], H->entries[j].val ); + } + + fclose( out ); + + /*sprintf( fname, "%s.b_s%d", control->sim_name, step ); + out = fopen( fname, "w" ); + for( i = 0; i < system->N; i++ ) + fprintf( out, "%12.7f\n", workspace->b_s[i] ); + fclose( out ); + + sprintf( fname, "%s.b_t%d", control->sim_name, step ); + out = fopen( fname, "w" ); + for( i = 0; i < system->N; i++ ) + fprintf( out, "%12.7f\n", workspace->b_t[i] ); + fclose( out );*/ } -void Print_Charges( reax_system *system, control_params *control, - static_storage *workspace, int step ) +void Print_Charges( reax_system *system, control_params *control, + static_storage *workspace, int step ) { - int i; - char fname[100]; - FILE *fout; + int i; + char fname[100]; + FILE *fout; - sprintf( fname, "%s.q%d", control->sim_name, step ); - fout = fopen( fname, "w" ); + sprintf( fname, "%s.q%d", control->sim_name, step ); + fout = fopen( fname, "w" ); - for( i = 0; i < system->N; ++i ) - fprintf( fout, "%6d%12.7f%12.7f%12.7f\n", - workspace->orig_id[i], - workspace->s[0][i], workspace->t[0][i], system->atoms[i].q ); + for ( i = 0; i < system->N; ++i ) + fprintf( fout, "%6d%12.7f%12.7f%12.7f\n", + workspace->orig_id[i], + workspace->s[0][i], workspace->t[0][i], system->atoms[i].q ); - fclose( fout ); + fclose( fout ); } -void Print_Soln( static_storage *workspace, - real *x, real *b_prm, real *b, int N ) +void Print_Soln( static_storage *workspace, + real *x, real *b_prm, real *b, int N ) { - int i; + int i; - fprintf( stdout, "%6s%10s%10s%10s\n", "id", "x", "b_prm", "b" ); + fprintf( stdout, "%6s%10s%10s%10s\n", "id", "x", "b_prm", "b" ); - for( i = 0; i < N; ++i ) - fprintf( stdout, "%6d%10.4f%10.4f%10.4f\n", - workspace->orig_id[i], x[i], b_prm[i], b[i] ); + for ( i = 0; i < N; ++i ) + fprintf( stdout, "%6d%10.4f%10.4f%10.4f\n", + workspace->orig_id[i], x[i], b_prm[i], b[i] ); - fflush( stdout ); + fflush( stdout ); } void Print_Sparse_Matrix( sparse_matrix *A ) { - int i, j; - - for( i = 0; i < A->n; ++i ) { - fprintf( stderr, "i:%d j(val):", i ); - for( j = A->start[i]; j < A->start[i+1]; ++j ) - fprintf( stderr, "%d(%.4f) ", A->entries[j].j, A->entries[j].val ); - fprintf( stderr, "\n" ); - } + int i, j; + + for ( i = 0; i < A->n; ++i ) + { + fprintf( stderr, "i:%d j(val):", i ); + for ( j = A->start[i]; j < A->start[i + 1]; ++j ) + fprintf( stderr, "%d(%.4f) ", A->entries[j].j, A->entries[j].val ); + fprintf( stderr, "\n" ); + } } void Print_Sparse_Matrix2( sparse_matrix *A, char *fname ) { - int i, j; - FILE *f = fopen( fname, "w" ); + int i, j; + FILE *f = fopen( fname, "w" ); - for( i = 0; i < A->n; ++i ) - for( j = A->start[i]; j < A->start[i+1]; ++j ) - fprintf( f, "%d%d %.15e\n", A->entries[j].j, i, A->entries[j].val ); + for ( i = 0; i < A->n; ++i ) + for ( j = A->start[i]; j < A->start[i + 1]; ++j ) + fprintf( f, "%d%d %.15e\n", A->entries[j].j, i, A->entries[j].val ); - fclose(f); + fclose(f); } void Print_Bonds( reax_system *system, list *bonds, char *fname ) { - int i, pj; - bond_data *pbond; - bond_order_data *bo_ij; - FILE *f = fopen( fname, "w" ); - - for( i = 0; i < system->N; ++i ) - for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) { - pbond = &(bonds->select.bond_list[pj]); - bo_ij = &(pbond->bo_data); - //fprintf( f, "%6d%6d%23.15e%23.15e%23.15e%23.15e%23.15e\n", - // i+1, pbond->nbr+1, pbond->d, - // bo_ij->BO, bo_ij->BO_s, bo_ij->BO_pi, bo_ij->BO_pi2 ); - fprintf( f, "%6d%6d %9.5f %9.5f\n", - i+1, pbond->nbr+1, pbond->d, bo_ij->BO ); - } - fclose(f); + int i, pj; + bond_data *pbond; + bond_order_data *bo_ij; + FILE *f = fopen( fname, "w" ); + + for ( i = 0; i < system->N; ++i ) + for ( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) + { + pbond = &(bonds->select.bond_list[pj]); + bo_ij = &(pbond->bo_data); + //fprintf( f, "%6d%6d%23.15e%23.15e%23.15e%23.15e%23.15e\n", + // i+1, pbond->nbr+1, pbond->d, + // bo_ij->BO, bo_ij->BO_s, bo_ij->BO_pi, bo_ij->BO_pi2 ); + fprintf( f, "%6d%6d %9.5f %9.5f\n", + i + 1, pbond->nbr + 1, pbond->d, bo_ij->BO ); + } + fclose(f); } void Print_Bond_List2( reax_system *system, list *bonds, char *fname ) { - int i,j, id_i, id_j, nbr, pj; - FILE *f = fopen( fname, "w" ); - int temp[500]; - int num=0; - - for( i = 0; i < system->N; ++i ) { - num=0; - id_i = i+1; //system->atoms[i].orig_id; - fprintf( f, "%6d:", id_i); - for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) { - nbr = bonds->select.bond_list[pj].nbr; - id_j = nbr+1; //system->my_atoms[nbr].orig_id; - if( id_i < id_j ) - temp[num++] = id_j; + int i, j, id_i, id_j, nbr, pj; + FILE *f = fopen( fname, "w" ); + int temp[500]; + int num = 0; + + for ( i = 0; i < system->N; ++i ) + { + num = 0; + id_i = i + 1; //system->atoms[i].orig_id; + fprintf( f, "%6d:", id_i); + for ( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) + { + nbr = bonds->select.bond_list[pj].nbr; + id_j = nbr + 1; //system->my_atoms[nbr].orig_id; + if ( id_i < id_j ) + temp[num++] = id_j; + } + + qsort(&temp, num, sizeof(int), fn_qsort_intcmp); + for (j = 0; j < num; j++) + fprintf(f, "%6d", temp[j] ); + fprintf(f, "\n"); } - - qsort(&temp, num, sizeof(int), fn_qsort_intcmp); - for(j=0; j < num; j++) - fprintf(f, "%6d", temp[j] ); - fprintf(f, "\n"); - } } #ifdef LGJ Print_XYZ_Serial(reax_system* system, static_storage *workspace) { - rvec p; - - char fname[100]; - FILE *fout; - sprintf( fname, "READ_PDB.0" ); - fout = fopen( fname, "w" ); -int i; -for(i=0; i < system->N; i++) - fprintf( fout, "%6d%24.15e%24.15e%24.15e\n", - workspace->orig_id[i], - p[0] = system->atoms[i].x[0], - p[1] = system->atoms[i].x[1], - p[2] = system->atoms[i].x[2]); - - - fclose(fout); + rvec p; + + char fname[100]; + FILE *fout; + sprintf( fname, "READ_PDB.0" ); + fout = fopen( fname, "w" ); + int i; + for (i = 0; i < system->N; i++) + fprintf( fout, "%6d%24.15e%24.15e%24.15e\n", + workspace->orig_id[i], + p[0] = system->atoms[i].x[0], + p[1] = system->atoms[i].x[1], + p[2] = system->atoms[i].x[2]); + + + fclose(fout); } #endif diff --git a/puremd_rc_1003/sPuReMD/print_utils.h b/puremd_rc_1003/sPuReMD/print_utils.h index c13cc87b..8b3b3635 100644 --- a/puremd_rc_1003/sPuReMD/print_utils.h +++ b/puremd_rc_1003/sPuReMD/print_utils.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -24,28 +24,28 @@ #include "mytypes.h" -typedef void (*print_interaction)(reax_system*,control_params*,simulation_data*, - static_storage*,list**,output_controls*); +typedef void (*print_interaction)(reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls*); print_interaction Print_Interactions[NO_OF_INTERACTIONS]; char *Get_Element( reax_system*, int ); char *Get_Atom_Name( reax_system*, int ); -void Print_Near_Neighbors( reax_system*, control_params*, static_storage*, - list** ); +void Print_Near_Neighbors( reax_system*, control_params*, static_storage*, + list** ); -void Print_Far_Neighbors( reax_system*, control_params*, static_storage*, - list** ); +void Print_Far_Neighbors( reax_system*, control_params*, static_storage*, + list** ); -void Print_Total_Force( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); +void Print_Total_Force( reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls* ); -void Output_Results( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); +void Output_Results( reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls* ); -void Print_Bond_Orders( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); +void Print_Bond_Orders( reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls* ); void Print_Linear_System( reax_system*, control_params*, static_storage*, int ); @@ -61,24 +61,24 @@ void Print_Bonds( reax_system*, list*, char* ); void Print_Bond_List2( reax_system*, list*, char* ); #ifdef TEST_FORCES -void Dummy_Printer( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); -void Print_Bond_Forces( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); -void Print_LonePair_Forces( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); +void Dummy_Printer( reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls* ); +void Print_Bond_Forces( reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls* ); +void Print_LonePair_Forces( reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls* ); void Print_OverUnderCoor_Forces(reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls*); -void Print_Three_Body_Forces( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); + static_storage*, list**, output_controls*); +void Print_Three_Body_Forces( reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls* ); void Print_Hydrogen_Bond_Forces(reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls*); -void Print_Four_Body_Forces( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); -void Print_vdW_Coulomb_Forces( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); -void Compare_Total_Forces( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); + static_storage*, list**, output_controls*); +void Print_Four_Body_Forces( reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls* ); +void Print_vdW_Coulomb_Forces( reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls* ); +void Compare_Total_Forces( reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls* ); void Init_Force_Test_Functions( ); #endif diff --git a/puremd_rc_1003/sPuReMD/random.c b/puremd_rc_1003/sPuReMD/random.c index 0771d635..f3a5096c 100644 --- a/puremd_rc_1003/sPuReMD/random.c +++ b/puremd_rc_1003/sPuReMD/random.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -27,7 +27,7 @@ 0 <= Random(range) < range */ double Random(double range) { - return (random()*range)/2147483647L; + return (random() * range) / 2147483647L; } /* This function seeds the system pseudo random number generator with @@ -35,23 +35,23 @@ double Random(double range) the system */ void Randomize() { - srandom(time(NULL)); + srandom(time(NULL)); } /* GRandom return random number with gaussian distribution with mean and standard deviation "sigma" */ double GRandom(double mean, double sigma) { - double v1 = Random(2.0) - 1.0; - double v2 = Random(2.0) - 1.0; - double rsq = v1*v1 + v2*v2; + double v1 = Random(2.0) - 1.0; + double v2 = Random(2.0) - 1.0; + double rsq = v1 * v1 + v2 * v2; - while (rsq >= 1.0 || rsq == 0.0) + while (rsq >= 1.0 || rsq == 0.0) { - v1 = Random(2.0) - 1.0; - v2 = Random(2.0) - 1.0; - rsq = v1*v1 + v2*v2; + v1 = Random(2.0) - 1.0; + v2 = Random(2.0) - 1.0; + rsq = v1 * v1 + v2 * v2; } - return mean+v1*sigma*sqrt(-2.0*log(rsq)/rsq); + return mean + v1 * sigma * sqrt(-2.0 * log(rsq) / rsq); } diff --git a/puremd_rc_1003/sPuReMD/random.h b/puremd_rc_1003/sPuReMD/random.h index 78d9a395..a90b181d 100644 --- a/puremd_rc_1003/sPuReMD/random.h +++ b/puremd_rc_1003/sPuReMD/random.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ diff --git a/puremd_rc_1003/sPuReMD/reset_utils.c b/puremd_rc_1003/sPuReMD/reset_utils.c index 7c0e7353..36d6b414 100644 --- a/puremd_rc_1003/sPuReMD/reset_utils.c +++ b/puremd_rc_1003/sPuReMD/reset_utils.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -26,138 +26,140 @@ void Reset_Atoms( reax_system* system ) { - int i; + int i; - for( i = 0; i < system->N; ++i ) - memset( system->atoms[i].f, 0.0, sizeof(rvec) ); + for ( i = 0; i < system->N; ++i ) + memset( system->atoms[i].f, 0.0, sizeof(rvec) ); } void Reset_Pressures( simulation_data *data ) { - rtensor_MakeZero( data->flex_bar.P ); - data->iso_bar.P = 0; - rvec_MakeZero( data->int_press ); - rvec_MakeZero( data->ext_press ); - /* fprintf( stderr, "reset: ext_press (%12.6f %12.6f %12.6f)\n", - data->ext_press[0], data->ext_press[1], data->ext_press[2] ); */ + rtensor_MakeZero( data->flex_bar.P ); + data->iso_bar.P = 0; + rvec_MakeZero( data->int_press ); + rvec_MakeZero( data->ext_press ); + /* fprintf( stderr, "reset: ext_press (%12.6f %12.6f %12.6f)\n", + data->ext_press[0], data->ext_press[1], data->ext_press[2] ); */ } void Reset_Simulation_Data( simulation_data* data ) { - data->E_BE = 0; - data->E_Ov = 0; - data->E_Un = 0; - data->E_Lp = 0; - data->E_Ang = 0; - data->E_Pen = 0; - data->E_Coa = 0; - data->E_HB = 0; - data->E_Tor = 0; - data->E_Con = 0; - data->E_vdW = 0; - data->E_Ele = 0; - data->E_Kin = 0; + data->E_BE = 0; + data->E_Ov = 0; + data->E_Un = 0; + data->E_Lp = 0; + data->E_Ang = 0; + data->E_Pen = 0; + data->E_Coa = 0; + data->E_HB = 0; + data->E_Tor = 0; + data->E_Con = 0; + data->E_vdW = 0; + data->E_Ele = 0; + data->E_Kin = 0; } #ifdef TEST_FORCES void Reset_Test_Forces( reax_system *system, static_storage *workspace ) { - memset( workspace->f_ele, 0, system->N * sizeof(rvec) ); - memset( workspace->f_vdw, 0, system->N * sizeof(rvec) ); - memset( workspace->f_bo, 0, system->N * sizeof(rvec) ); - memset( workspace->f_be, 0, system->N * sizeof(rvec) ); - memset( workspace->f_lp, 0, system->N * sizeof(rvec) ); - memset( workspace->f_ov, 0, system->N * sizeof(rvec) ); - memset( workspace->f_un, 0, system->N * sizeof(rvec) ); - memset( workspace->f_ang, 0, system->N * sizeof(rvec) ); - memset( workspace->f_coa, 0, system->N * sizeof(rvec) ); - memset( workspace->f_pen, 0, system->N * sizeof(rvec) ); - memset( workspace->f_hb, 0, system->N * sizeof(rvec) ); - memset( workspace->f_tor, 0, system->N * sizeof(rvec) ); - memset( workspace->f_con, 0, system->N * sizeof(rvec) ); + memset( workspace->f_ele, 0, system->N * sizeof(rvec) ); + memset( workspace->f_vdw, 0, system->N * sizeof(rvec) ); + memset( workspace->f_bo, 0, system->N * sizeof(rvec) ); + memset( workspace->f_be, 0, system->N * sizeof(rvec) ); + memset( workspace->f_lp, 0, system->N * sizeof(rvec) ); + memset( workspace->f_ov, 0, system->N * sizeof(rvec) ); + memset( workspace->f_un, 0, system->N * sizeof(rvec) ); + memset( workspace->f_ang, 0, system->N * sizeof(rvec) ); + memset( workspace->f_coa, 0, system->N * sizeof(rvec) ); + memset( workspace->f_pen, 0, system->N * sizeof(rvec) ); + memset( workspace->f_hb, 0, system->N * sizeof(rvec) ); + memset( workspace->f_tor, 0, system->N * sizeof(rvec) ); + memset( workspace->f_con, 0, system->N * sizeof(rvec) ); } #endif void Reset_Workspace( reax_system *system, static_storage *workspace ) { - memset( workspace->total_bond_order, 0, system->N * sizeof( real ) ); - memset( workspace->dDeltap_self, 0, system->N * sizeof( rvec ) ); + memset( workspace->total_bond_order, 0, system->N * sizeof( real ) ); + memset( workspace->dDeltap_self, 0, system->N * sizeof( rvec ) ); - memset( workspace->CdDelta, 0, system->N * sizeof( real ) ); - //memset( workspace->virial_forces, 0, system->N * sizeof( rvec ) ); + memset( workspace->CdDelta, 0, system->N * sizeof( real ) ); + //memset( workspace->virial_forces, 0, system->N * sizeof( rvec ) ); #ifdef TEST_FORCES - memset( workspace->dDelta, 0, sizeof(rvec) * system->N ); - Reset_Test_Forces( system, workspace ); + memset( workspace->dDelta, 0, sizeof(rvec) * system->N ); + Reset_Test_Forces( system, workspace ); #endif } -void Reset_Neighbor_Lists( reax_system *system, control_params *control, - static_storage *workspace, list **lists ) +void Reset_Neighbor_Lists( reax_system *system, control_params *control, + static_storage *workspace, list **lists ) { - int i, tmp; - list *bonds = (*lists) + BONDS; - list *hbonds = (*lists) + HBONDS; - - for( i = 0; i < system->N; ++i ) { - tmp = Start_Index( i, bonds ); - Set_End_Index( i, tmp, bonds ); - } - - if( control->hb_cut > 0 ) - for( i = 0; i < system->N; ++i ) - if( system->reaxprm.sbp[system->atoms[i].type].p_hbond == 1) { - tmp = Start_Index( workspace->hbond_index[i], hbonds ); - Set_End_Index( workspace->hbond_index[i], tmp, hbonds ); - /* fprintf( stderr, "i:%d, hbond: %d-%d\n", - i, Start_Index( workspace->hbond_index[i], hbonds ), - End_Index( workspace->hbond_index[i], hbonds ) );*/ - } + int i, tmp; + list *bonds = (*lists) + BONDS; + list *hbonds = (*lists) + HBONDS; + + for ( i = 0; i < system->N; ++i ) + { + tmp = Start_Index( i, bonds ); + Set_End_Index( i, tmp, bonds ); + } + + if ( control->hb_cut > 0 ) + for ( i = 0; i < system->N; ++i ) + if ( system->reaxprm.sbp[system->atoms[i].type].p_hbond == 1) + { + tmp = Start_Index( workspace->hbond_index[i], hbonds ); + Set_End_Index( workspace->hbond_index[i], tmp, hbonds ); + /* fprintf( stderr, "i:%d, hbond: %d-%d\n", + i, Start_Index( workspace->hbond_index[i], hbonds ), + End_Index( workspace->hbond_index[i], hbonds ) );*/ + } } -void Reset( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, list **lists ) +void Reset( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, list **lists ) { - Reset_Atoms( system ); - - Reset_Simulation_Data( data ); + Reset_Atoms( system ); - if( control->ensemble == NPT || control->ensemble == sNPT || - control->ensemble == iNPT ) - Reset_Pressures( data ); + Reset_Simulation_Data( data ); - Reset_Workspace( system, workspace ); + if ( control->ensemble == NPT || control->ensemble == sNPT || + control->ensemble == iNPT ) + Reset_Pressures( data ); - Reset_Neighbor_Lists( system, control, workspace, lists ); + Reset_Workspace( system, workspace ); -#if defined(DEBUG_FOCUS) - fprintf( stderr, "reset - "); + Reset_Neighbor_Lists( system, control, workspace, lists ); + +#if defined(DEBUG_FOCUS) + fprintf( stderr, "reset - "); #endif } void Reset_Grid( grid *g ) { - int i, j, k; + int 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->top[i][j][k] = 0; } void Reset_Marks( grid *g, ivec *grid_stack, int grid_top ) { - int i; - - for( i = 0; i < grid_top; ++i ) - g->mark[grid_stack[i][0]][grid_stack[i][1]][grid_stack[i][2]] = 0; + int i; + + for ( i = 0; i < grid_top; ++i ) + g->mark[grid_stack[i][0]][grid_stack[i][1]][grid_stack[i][2]] = 0; } diff --git a/puremd_rc_1003/sPuReMD/reset_utils.h b/puremd_rc_1003/sPuReMD/reset_utils.h index bda3b390..aadfe736 100644 --- a/puremd_rc_1003/sPuReMD/reset_utils.h +++ b/puremd_rc_1003/sPuReMD/reset_utils.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -36,11 +36,11 @@ void Reset_Test_Forces( reax_system*, static_storage* ); void Reset_Workspace( reax_system*, static_storage* ); -void Reset_Neighbor_Lists( reax_system*, control_params*, - static_storage*, list** ); +void Reset_Neighbor_Lists( reax_system*, control_params*, + static_storage*, list** ); -void Reset( reax_system*, control_params*, simulation_data*, - static_storage*, list** ); +void Reset( reax_system*, control_params*, simulation_data*, + static_storage*, list** ); //void Reset_Neighbor_Lists( reax_system*, static_storage*, list** ); diff --git a/puremd_rc_1003/sPuReMD/restart.c b/puremd_rc_1003/sPuReMD/restart.c index c594de14..c15d51c5 100644 --- a/puremd_rc_1003/sPuReMD/restart.c +++ b/puremd_rc_1003/sPuReMD/restart.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -23,221 +23,225 @@ #include "box.h" #include "vector.h" -void Write_Binary_Restart( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace ) +void Write_Binary_Restart( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace ) { - int i; - char fname[MAX_STR]; - FILE *fres; - reax_atom *p_atom; - restart_header res_header; - restart_atom res_data; - - sprintf( fname, "%s.res%d", control->sim_name, data->step ); - fres = fopen( fname, "wb" ); - - res_header.step = data->step; - res_header.N = system->N; - res_header.T = data->therm.T; - res_header.xi = data->therm.xi; - res_header.v_xi = data->therm.v_xi; - res_header.v_xi_old = data->therm.v_xi_old; - res_header.G_xi = data->therm.G_xi; - rtensor_Copy( res_header.box, system->box.box ); - fwrite(&res_header, sizeof(restart_header), 1, fres); - - for( i = 0; i < system->N; ++i ) { - p_atom = &( system->atoms[i] ); - res_data.orig_id = workspace->orig_id[i]; - res_data.type = p_atom->type; - strncpy( res_data.name, p_atom->name, 8 ); - rvec_Copy( res_data.x, p_atom->x ); - rvec_Copy( res_data.v, p_atom->v ); - fwrite( &res_data, sizeof(restart_atom), 1, fres ); - } - - fclose( fres ); - -#if defined(DEBUG_FOCUS) + int i; + char fname[MAX_STR]; + FILE *fres; + reax_atom *p_atom; + restart_header res_header; + restart_atom res_data; + + sprintf( fname, "%s.res%d", control->sim_name, data->step ); + fres = fopen( fname, "wb" ); + + res_header.step = data->step; + res_header.N = system->N; + res_header.T = data->therm.T; + res_header.xi = data->therm.xi; + res_header.v_xi = data->therm.v_xi; + res_header.v_xi_old = data->therm.v_xi_old; + res_header.G_xi = data->therm.G_xi; + rtensor_Copy( res_header.box, system->box.box ); + fwrite(&res_header, sizeof(restart_header), 1, fres); + + for ( i = 0; i < system->N; ++i ) + { + p_atom = &( system->atoms[i] ); + res_data.orig_id = workspace->orig_id[i]; + res_data.type = p_atom->type; + strncpy( res_data.name, p_atom->name, 8 ); + rvec_Copy( res_data.x, p_atom->x ); + rvec_Copy( res_data.v, p_atom->v ); + fwrite( &res_data, sizeof(restart_atom), 1, fres ); + } + + fclose( fres ); + +#if defined(DEBUG_FOCUS) fprintf( stderr, "write restart - " ); #endif } -void Read_Binary_Restart( char *fname, reax_system *system, - control_params *control, simulation_data *data, - static_storage *workspace ) +void Read_Binary_Restart( char *fname, reax_system *system, + control_params *control, simulation_data *data, + static_storage *workspace ) { - int i; - FILE *fres; - reax_atom *p_atom; - restart_header res_header; - restart_atom res_data; - - fres = fopen( fname, "rb" ); - - 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; - data->therm.v_xi_old = res_header.v_xi_old; - data->therm.G_xi = res_header.G_xi; - Update_Box( res_header.box, &(system->box) ); + int i; + FILE *fres; + reax_atom *p_atom; + restart_header res_header; + restart_atom res_data; + + fres = fopen( fname, "rb" ); + + 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; + data->therm.v_xi_old = res_header.v_xi_old; + data->therm.G_xi = res_header.G_xi; + Update_Box( res_header.box, &(system->box) ); #if defined(DEBUG_FOCUS) - fprintf( stderr, "restart step: %d\n", data->prev_steps ); - fprintf( stderr, "restart thermostat: %10.6f %10.6f %10.6f %10.6f %10.6f\n", - data->therm.T, data->therm.xi, - data->therm.v_xi, data->therm.v_xi_old, data->therm.G_xi ); - fprintf( stderr, "restart box:\n" ); - fprintf( stderr, "%9.5f %9.5f %9.5f\n%9.5f %9.5f %9.5f\n%9.5f %9.5f %9.5f\n", - 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], - system->box.box[2][0],system->box.box[2][1],system->box.box[2][2] ); + fprintf( stderr, "restart step: %d\n", data->prev_steps ); + fprintf( stderr, "restart thermostat: %10.6f %10.6f %10.6f %10.6f %10.6f\n", + data->therm.T, data->therm.xi, + data->therm.v_xi, data->therm.v_xi_old, data->therm.G_xi ); + fprintf( stderr, "restart box:\n" ); + fprintf( stderr, "%9.5f %9.5f %9.5f\n%9.5f %9.5f %9.5f\n%9.5f %9.5f %9.5f\n", + 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], + system->box.box[2][0], system->box.box[2][1], system->box.box[2][2] ); #endif - /* memory allocations for atoms, atom maps, bond restrictions */ - system->atoms = (reax_atom*) calloc( system->N, sizeof(reax_atom) ); + /* memory allocations for atoms, atom maps, bond restrictions */ + system->atoms = (reax_atom*) calloc( system->N, sizeof(reax_atom) ); - workspace->map_serials = (int*) calloc( MAX_ATOM_ID, sizeof(int) ); - for( i = 0; i < MAX_ATOM_ID; ++i ) - workspace->map_serials[i] = -1; + workspace->map_serials = (int*) calloc( MAX_ATOM_ID, sizeof(int) ); + for ( i = 0; i < MAX_ATOM_ID; ++i ) + workspace->map_serials[i] = -1; - workspace->orig_id = (int*) calloc( system->N, sizeof(int) ); - workspace->restricted = (int*) calloc( system->N, sizeof(int) ); - workspace->restricted_list = (int**) calloc( system->N, sizeof(int*) ); - for( i = 0; i < system->N; ++i ) - workspace->restricted_list[i] = (int*) calloc( MAX_RESTRICT, sizeof(int) ); + workspace->orig_id = (int*) calloc( system->N, sizeof(int) ); + workspace->restricted = (int*) calloc( system->N, sizeof(int) ); + workspace->restricted_list = (int**) calloc( system->N, sizeof(int*) ); + for ( i = 0; i < system->N; ++i ) + workspace->restricted_list[i] = (int*) calloc( MAX_RESTRICT, sizeof(int) ); - for( i = 0; i < system->N; ++i ) { - fread( &res_data, sizeof(restart_atom), 1, fres); + for ( i = 0; i < system->N; ++i ) + { + fread( &res_data, sizeof(restart_atom), 1, fres); - workspace->orig_id[i] = res_data.orig_id; - workspace->map_serials[res_data.orig_id] = i; + workspace->orig_id[i] = res_data.orig_id; + workspace->map_serials[res_data.orig_id] = i; - p_atom = &( system->atoms[i] ); - p_atom->type = res_data.type; - strcpy( p_atom->name, res_data.name ); - rvec_Copy( p_atom->x, res_data.x ); - rvec_Copy( p_atom->v, res_data.v ); - } + p_atom = &( system->atoms[i] ); + p_atom->type = res_data.type; + strcpy( p_atom->name, res_data.name ); + rvec_Copy( p_atom->x, res_data.x ); + rvec_Copy( p_atom->v, res_data.v ); + } #if defined(DEBUG_FOCUS) - fprintf( stderr, "system->N: %d, i: %d\n", system->N, i ); + fprintf( stderr, "system->N: %d, i: %d\n", system->N, i ); #endif - - fclose( fres ); - - data->step = data->prev_steps; - // nsteps is updated based on the number of steps in the previous run - control->nsteps += data->prev_steps; + + fclose( fres ); + + data->step = data->prev_steps; + // nsteps is updated based on the number of steps in the previous run + control->nsteps += data->prev_steps; } -void Write_ASCII_Restart( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace ) +void Write_ASCII_Restart( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace ) { - int i; - char fname[MAX_STR]; - FILE *fres; - reax_atom *p_atom; - - sprintf( fname, "%s.res%d", control->sim_name, data->step ); - fres = fopen( fname, "w" ); - - fprintf( fres, RESTART_HEADER, - data->step, system->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], - system->box.box[2][0], system->box.box[2][1], system->box.box[2][2]); - fflush(fres); - - for( i = 0; i < system->N; ++i ) { - p_atom = &( system->atoms[i] ); - fprintf( fres, RESTART_LINE, - workspace->orig_id[i], p_atom->type, p_atom->name, - p_atom->x[0], p_atom->x[1], p_atom->x[2], - p_atom->v[0], p_atom->v[1], p_atom->v[2] ); - } - - fclose( fres ); - -#if defined(DEBUG_FOCUS) + int i; + char fname[MAX_STR]; + FILE *fres; + reax_atom *p_atom; + + sprintf( fname, "%s.res%d", control->sim_name, data->step ); + fres = fopen( fname, "w" ); + + fprintf( fres, RESTART_HEADER, + data->step, system->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], + system->box.box[2][0], system->box.box[2][1], system->box.box[2][2]); + fflush(fres); + + for ( i = 0; i < system->N; ++i ) + { + p_atom = &( system->atoms[i] ); + fprintf( fres, RESTART_LINE, + workspace->orig_id[i], p_atom->type, p_atom->name, + p_atom->x[0], p_atom->x[1], p_atom->x[2], + p_atom->v[0], p_atom->v[1], p_atom->v[2] ); + } + + fclose( fres ); + +#if defined(DEBUG_FOCUS) fprintf( stderr, "write restart - " ); #endif } -void Read_ASCII_Restart( char *fname, reax_system *system, - control_params *control, simulation_data *data, - static_storage *workspace ) +void Read_ASCII_Restart( char *fname, reax_system *system, + control_params *control, simulation_data *data, + static_storage *workspace ) { - int i; - FILE *fres; - reax_atom *p_atom; + int i; + FILE *fres; + reax_atom *p_atom; - fres = fopen( fname, "r" ); + fres = fopen( fname, "r" ); - /* header */ - fscanf( fres, READ_RESTART_HEADER, - &data->prev_steps, &system->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], - &system->box.box[2][0],&system->box.box[2][1],&system->box.box[2][2]); - Make_Consistent( &(system->box) ); + /* header */ + fscanf( fres, READ_RESTART_HEADER, + &data->prev_steps, &system->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], + &system->box.box[2][0], &system->box.box[2][1], &system->box.box[2][2]); + Make_Consistent( &(system->box) ); #if defined(DEBUG_FOCUS) - fprintf( stderr, "restart step: %d\n", data->prev_steps ); - fprintf( stderr, "restart thermostat: %10.6f %10.6f %10.6f %10.6f %10.6f\n", - data->therm.T, data->therm.xi, - data->therm.v_xi, data->therm.v_xi_old, data->therm.G_xi ); - fprintf( stderr, "restart box:\n" ); - fprintf( stderr, "%9.5f %9.5f %9.5f\n%9.5f %9.5f %9.5f\n%9.5f %9.5f %9.5f\n", - 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], - system->box.box[2][0],system->box.box[2][1],system->box.box[2][2] ); + fprintf( stderr, "restart step: %d\n", data->prev_steps ); + fprintf( stderr, "restart thermostat: %10.6f %10.6f %10.6f %10.6f %10.6f\n", + data->therm.T, data->therm.xi, + data->therm.v_xi, data->therm.v_xi_old, data->therm.G_xi ); + fprintf( stderr, "restart box:\n" ); + fprintf( stderr, "%9.5f %9.5f %9.5f\n%9.5f %9.5f %9.5f\n%9.5f %9.5f %9.5f\n", + 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], + system->box.box[2][0], system->box.box[2][1], system->box.box[2][2] ); #endif - /* memory allocations for atoms, atom maps, bond restrictions */ - system->atoms = (reax_atom*) calloc( system->N, sizeof(reax_atom) ); - - workspace->map_serials = (int*) calloc( MAX_ATOM_ID, sizeof(int) ); - for( i = 0; i < MAX_ATOM_ID; ++i ) - workspace->map_serials[i] = -1; - - workspace->orig_id = (int*) calloc( system->N, sizeof(int) ); - workspace->restricted = (int*) calloc( system->N, sizeof(int) ); - workspace->restricted_list = (int**) calloc( system->N, sizeof(int*) ); - for( i = 0; i < system->N; ++i ) - workspace->restricted_list[i] = (int*) calloc( MAX_RESTRICT, sizeof(int) ); - - for( i = 0; i < system->N; ++i ) { - p_atom = &( system->atoms[i] ); - fscanf( fres, READ_RESTART_LINE, - &workspace->orig_id[i], &p_atom->type, p_atom->name, - &p_atom->x[0], &p_atom->x[1], &p_atom->x[2], - &p_atom->v[0], &p_atom->v[1], &p_atom->v[2] ); - workspace->map_serials[workspace->orig_id[i]] = i; - } - - fclose( fres ); - - data->step = data->prev_steps; - // nsteps is updated based on the number of steps in the previous run - control->nsteps += data->prev_steps; + /* memory allocations for atoms, atom maps, bond restrictions */ + system->atoms = (reax_atom*) calloc( system->N, sizeof(reax_atom) ); + + workspace->map_serials = (int*) calloc( MAX_ATOM_ID, sizeof(int) ); + for ( i = 0; i < MAX_ATOM_ID; ++i ) + workspace->map_serials[i] = -1; + + workspace->orig_id = (int*) calloc( system->N, sizeof(int) ); + workspace->restricted = (int*) calloc( system->N, sizeof(int) ); + workspace->restricted_list = (int**) calloc( system->N, sizeof(int*) ); + for ( i = 0; i < system->N; ++i ) + workspace->restricted_list[i] = (int*) calloc( MAX_RESTRICT, sizeof(int) ); + + for ( i = 0; i < system->N; ++i ) + { + p_atom = &( system->atoms[i] ); + fscanf( fres, READ_RESTART_LINE, + &workspace->orig_id[i], &p_atom->type, p_atom->name, + &p_atom->x[0], &p_atom->x[1], &p_atom->x[2], + &p_atom->v[0], &p_atom->v[1], &p_atom->v[2] ); + workspace->map_serials[workspace->orig_id[i]] = i; + } + + fclose( fres ); + + data->step = data->prev_steps; + // nsteps is updated based on the number of steps in the previous run + control->nsteps += data->prev_steps; } -void Write_Restart( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - output_controls *out_control ) +void Write_Restart( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + output_controls *out_control ) { - if( out_control->restart_format == WRITE_ASCII ) - Write_ASCII_Restart( system, control, data, workspace ); - else if( out_control->restart_format == WRITE_BINARY ) - Write_Binary_Restart( system, control, data, workspace ); + if ( out_control->restart_format == WRITE_ASCII ) + Write_ASCII_Restart( system, control, data, workspace ); + else if ( out_control->restart_format == WRITE_BINARY ) + Write_Binary_Restart( system, control, data, workspace ); } diff --git a/puremd_rc_1003/sPuReMD/restart.h b/puremd_rc_1003/sPuReMD/restart.h index 7249aa63..d0ea4ca8 100644 --- a/puremd_rc_1003/sPuReMD/restart.h +++ b/puremd_rc_1003/sPuReMD/restart.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -24,39 +24,41 @@ #include "mytypes.h" -typedef struct { - int step, N; - real T, xi, v_xi, v_xi_old, G_xi; - rtensor box; +typedef struct +{ + int step, N; + real T, xi, v_xi, v_xi_old, G_xi; + rtensor box; } restart_header; -typedef struct { - int orig_id, type; - char name[8]; - rvec x, v; +typedef struct +{ + int orig_id, type; + char name[8]; + rvec x, v; } restart_atom; #define RESTART_HEADER "%8d%12d%8.3f%8.3f%8.3f%8.3f%8.3f\n%15.5f%15.5f%15.5f\n%15.5f%15.5f%15.5f\n%15.5f%15.5f%15.5f\n" #define RESTART_HEADER_LINE_LEN 200 -/* step, system->bigN, data->therm.T, data->therm.xi, +/* step, system->bigN, data->therm.T, data->therm.xi, data->therm.v_xi data->therm.v_xi_old data->therm.G_xi system->big_box.box[0][0], [0][1], [0][2] system->big_box.box[1][0], [1][1], [1][2] system->big_box.box[2][0], [2][1], [2][2] */ #define RESTART_LINE "%6d%4d%8s%15.5f%15.5f%15.5f%15.5f%15.5f%15.5f\n" -#define RESTART_LINE_LEN 109 +#define RESTART_LINE_LEN 109 /* id type name x y z vx vy vz */ #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( char*, reax_system*, control_params*, - simulation_data*, static_storage* ); -void Read_ASCII_Restart( char*, reax_system*, control_params*, - simulation_data*, static_storage* ); +void Read_Binary_Restart( char*, reax_system*, control_params*, + simulation_data*, static_storage* ); +void Read_ASCII_Restart( char*, reax_system*, control_params*, + simulation_data*, static_storage* ); #endif diff --git a/puremd_rc_1003/sPuReMD/single_body_interactions.c b/puremd_rc_1003/sPuReMD/single_body_interactions.c index acfd4ef4..484104a8 100644 --- a/puremd_rc_1003/sPuReMD/single_body_interactions.c +++ b/puremd_rc_1003/sPuReMD/single_body_interactions.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -26,288 +26,295 @@ #include "vector.h" -void LonePair_OverUnder_Coordination_Energy( reax_system *system, - control_params *control, - simulation_data *data, - static_storage *workspace, - list **lists, - output_controls *out_control ) +void LonePair_OverUnder_Coordination_Energy( reax_system *system, + control_params *control, + simulation_data *data, + static_storage *workspace, + list **lists, + output_controls *out_control ) { - int i, j, pj, type_i, type_j; - real Delta_lpcorr, dfvl; - real e_lp, expvd2, inv_expvd2, dElp, CElp, DlpVi; - real e_lph, Di, vov3, deahu2dbo, deahu2dsbo; - real e_ov, CEover1, CEover2, CEover3, CEover4; - real exp_ovun1, exp_ovun2, sum_ovun1, sum_ovun2; - real exp_ovun2n, exp_ovun6, exp_ovun8; - real inv_exp_ovun1, inv_exp_ovun2, inv_exp_ovun2n, inv_exp_ovun8; - real e_un, CEunder1, CEunder2, CEunder3, CEunder4; - real p_lp1, p_lp2, p_lp3; - real p_ovun2, p_ovun3, p_ovun4, p_ovun5, p_ovun6, p_ovun7, p_ovun8; - - single_body_parameters *sbp_i, *sbp_j; - two_body_parameters *twbp; - bond_data *pbond; - bond_order_data *bo_ij; - list *bonds = (*lists) + BONDS; - - /* Initialize parameters */ - p_lp1 = system->reaxprm.gp.l[15]; - p_lp3 = system->reaxprm.gp.l[5]; - p_ovun3 = system->reaxprm.gp.l[32]; - p_ovun4 = system->reaxprm.gp.l[31]; - p_ovun6 = system->reaxprm.gp.l[6]; - p_ovun7 = system->reaxprm.gp.l[8]; - p_ovun8 = system->reaxprm.gp.l[9]; - - for( i = 0; i < system->N; ++i ) { - /* set the parameter pointer */ - type_i = system->atoms[i].type; - sbp_i = &(system->reaxprm.sbp[ type_i ]); - - /* lone-pair Energy */ - p_lp2 = sbp_i->p_lp2; - expvd2 = EXP( -75 * workspace->Delta_lp[i] ); - inv_expvd2 = 1. / (1. + expvd2 ); - - /* calculate the energy */ - data->E_Lp += e_lp = - p_lp2 * workspace->Delta_lp[i] * inv_expvd2; - - dElp = p_lp2 * inv_expvd2 + - 75 * p_lp2 * workspace->Delta_lp[i] * expvd2 * SQR(inv_expvd2); - CElp = dElp * workspace->dDelta_lp[i]; - - workspace->CdDelta[i] += CElp; // lp - 1st term + int i, j, pj, type_i, type_j; + real Delta_lpcorr, dfvl; + real e_lp, expvd2, inv_expvd2, dElp, CElp, DlpVi; + real e_lph, Di, vov3, deahu2dbo, deahu2dsbo; + real e_ov, CEover1, CEover2, CEover3, CEover4; + real exp_ovun1, exp_ovun2, sum_ovun1, sum_ovun2; + real exp_ovun2n, exp_ovun6, exp_ovun8; + real inv_exp_ovun1, inv_exp_ovun2, inv_exp_ovun2n, inv_exp_ovun8; + real e_un, CEunder1, CEunder2, CEunder3, CEunder4; + real p_lp1, p_lp2, p_lp3; + real p_ovun2, p_ovun3, p_ovun4, p_ovun5, p_ovun6, p_ovun7, p_ovun8; + + single_body_parameters *sbp_i, *sbp_j; + two_body_parameters *twbp; + bond_data *pbond; + bond_order_data *bo_ij; + list *bonds = (*lists) + BONDS; + + /* Initialize parameters */ + p_lp1 = system->reaxprm.gp.l[15]; + p_lp3 = system->reaxprm.gp.l[5]; + p_ovun3 = system->reaxprm.gp.l[32]; + p_ovun4 = system->reaxprm.gp.l[31]; + p_ovun6 = system->reaxprm.gp.l[6]; + p_ovun7 = system->reaxprm.gp.l[8]; + p_ovun8 = system->reaxprm.gp.l[9]; + + for ( i = 0; i < system->N; ++i ) + { + /* set the parameter pointer */ + type_i = system->atoms[i].type; + sbp_i = &(system->reaxprm.sbp[ type_i ]); + + /* lone-pair Energy */ + p_lp2 = sbp_i->p_lp2; + expvd2 = EXP( -75 * workspace->Delta_lp[i] ); + inv_expvd2 = 1. / (1. + expvd2 ); + + /* calculate the energy */ + data->E_Lp += e_lp = + p_lp2 * workspace->Delta_lp[i] * inv_expvd2; + + dElp = p_lp2 * inv_expvd2 + + 75 * p_lp2 * workspace->Delta_lp[i] * expvd2 * SQR(inv_expvd2); + CElp = dElp * workspace->dDelta_lp[i]; + + workspace->CdDelta[i] += CElp; // lp - 1st term #ifdef TEST_ENERGY - fprintf( out_control->elp, "%23.15e%23.15e%23.15e%23.15e\n", - p_lp2, workspace->Delta_lp_temp[i], expvd2, dElp ); - fprintf( out_control->elp, "%6d%23.15e%23.15e%23.15e\n", - workspace->orig_id[i]+1, workspace->nlp[i], e_lp, data->E_Lp ); + fprintf( out_control->elp, "%23.15e%23.15e%23.15e%23.15e\n", + p_lp2, workspace->Delta_lp_temp[i], expvd2, dElp ); + fprintf( out_control->elp, "%6d%23.15e%23.15e%23.15e\n", + workspace->orig_id[i] + 1, workspace->nlp[i], e_lp, data->E_Lp ); #endif #ifdef TEST_FORCES - Add_dDelta( system, lists, i, CElp, workspace->f_lp ); // lp - 1st term + Add_dDelta( system, lists, i, CElp, workspace->f_lp ); // lp - 1st term #endif - /* correction for C2 */ - if( system->reaxprm.gp.l[5] > 0.001 && - !strcmp( system->reaxprm.sbp[type_i].name, "C" ) ) - for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) - if( i < bonds->select.bond_list[pj].nbr ) { - j = bonds->select.bond_list[pj].nbr; - type_j = system->atoms[j].type; - - if( !strcmp( system->reaxprm.sbp[type_j].name, "C" ) ) { - twbp = &( system->reaxprm.tbp[type_i][type_j]); - bo_ij = &( bonds->select.bond_list[pj].bo_data ); - Di = workspace->Delta[i]; - vov3 = bo_ij->BO - Di - 0.040*POW(Di, 4.); - - if( vov3 > 3. ) { - data->E_Lp += e_lph = p_lp3 * SQR(vov3-3.0); - //estrain(i) += e_lph; - - deahu2dbo = 2.*p_lp3*(vov3 - 3.); - deahu2dsbo = 2.*p_lp3*(vov3 - 3.)*(-1. - 0.16*POW(Di, 3.)); - - bo_ij->Cdbo += deahu2dbo; - workspace->CdDelta[i] += deahu2dsbo; + /* correction for C2 */ + if ( system->reaxprm.gp.l[5] > 0.001 && + !strcmp( system->reaxprm.sbp[type_i].name, "C" ) ) + for ( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) + if ( i < bonds->select.bond_list[pj].nbr ) + { + j = bonds->select.bond_list[pj].nbr; + type_j = system->atoms[j].type; + + if ( !strcmp( system->reaxprm.sbp[type_j].name, "C" ) ) + { + twbp = &( system->reaxprm.tbp[type_i][type_j]); + bo_ij = &( bonds->select.bond_list[pj].bo_data ); + Di = workspace->Delta[i]; + vov3 = bo_ij->BO - Di - 0.040 * POW(Di, 4.); + + if ( vov3 > 3. ) + { + data->E_Lp += e_lph = p_lp3 * SQR(vov3 - 3.0); + //estrain(i) += e_lph; + + deahu2dbo = 2.*p_lp3 * (vov3 - 3.); + deahu2dsbo = 2.*p_lp3 * (vov3 - 3.) * (-1. - 0.16 * POW(Di, 3.)); + + bo_ij->Cdbo += deahu2dbo; + workspace->CdDelta[i] += deahu2dsbo; #ifdef TEST_ENERGY - fprintf(out_control->elp,"C2cor%6d%6d%23.15e%23.15e%23.15e\n", - // workspace->orig_id[i], workspace->orig_id[j], - i+1, j+1, e_lph, deahu2dbo, deahu2dsbo ); + fprintf(out_control->elp, "C2cor%6d%6d%23.15e%23.15e%23.15e\n", + // workspace->orig_id[i], workspace->orig_id[j], + i + 1, j + 1, e_lph, deahu2dbo, deahu2dsbo ); #endif #ifdef TEST_FORCES - Add_dBO(system, lists, i, pj, deahu2dbo, workspace->f_lp); - Add_dDelta(system, lists, i, deahu2dsbo, workspace->f_lp); + Add_dBO(system, lists, i, pj, deahu2dbo, workspace->f_lp); + Add_dDelta(system, lists, i, deahu2dsbo, workspace->f_lp); #endif - } - } - - } - } - - - for( i = 0; i < system->N; ++i ) { - type_i = system->atoms[i].type; - sbp_i = &(system->reaxprm.sbp[ type_i ]); - - /* over-coordination energy */ - if( sbp_i->mass > 21.0 ) - dfvl = 0.0; - else dfvl = 1.0; // only for 1st-row elements - - p_ovun2 = sbp_i->p_ovun2; - sum_ovun1 = 0; - sum_ovun2 = 0; - - for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) { - j = bonds->select.bond_list[pj].nbr; - type_j = system->atoms[j].type; - bo_ij = &(bonds->select.bond_list[pj].bo_data); - sbp_j = &(system->reaxprm.sbp[ type_j ]); - twbp = &(system->reaxprm.tbp[ type_i ][ type_j ]); - - sum_ovun1 += twbp->p_ovun1 * twbp->De_s * bo_ij->BO; - sum_ovun2 += (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j])* - ( bo_ij->BO_pi + bo_ij->BO_pi2 ); - - /*fprintf( stdout, "%4d%4d%23.15e%23.15e%23.15e\n", - i+1, j+1, - dfvl * workspace->Delta_lp_temp[j], - sbp_j->nlp_opt, - workspace->nlp_temp[j] );*/ + } + } + + } } - - exp_ovun1 = p_ovun3 * EXP( p_ovun4 * sum_ovun2 ); - inv_exp_ovun1 = 1.0 / (1 + exp_ovun1); - Delta_lpcorr = workspace->Delta[i] - - (dfvl*workspace->Delta_lp_temp[i]) * inv_exp_ovun1; - - exp_ovun2 = EXP( p_ovun2 * Delta_lpcorr ); - inv_exp_ovun2 = 1.0 / (1.0 + exp_ovun2); - - DlpVi = 1.0 / (Delta_lpcorr + sbp_i->valency + 1e-8 ); - CEover1 = Delta_lpcorr * DlpVi * inv_exp_ovun2; - - data->E_Ov += e_ov = sum_ovun1 * CEover1; - - CEover2 = sum_ovun1 * DlpVi * inv_exp_ovun2 * - ( 1.0 - Delta_lpcorr*( DlpVi + p_ovun2 * exp_ovun2 * inv_exp_ovun2 ) ); - - CEover3 = CEover2 * (1.0 - dfvl*workspace->dDelta_lp[i]*inv_exp_ovun1 ); - - CEover4 = CEover2 * (dfvl*workspace->Delta_lp_temp[i]) * - p_ovun4 * exp_ovun1 * SQR(inv_exp_ovun1); - - - /* under-coordination potential */ - p_ovun2 = sbp_i->p_ovun2; - p_ovun5 = sbp_i->p_ovun5; - - exp_ovun2n = 1.0 / exp_ovun2; - exp_ovun6 = EXP( p_ovun6 * Delta_lpcorr ); - exp_ovun8 = p_ovun7 * EXP(p_ovun8 * sum_ovun2); - inv_exp_ovun2n = 1.0 / (1.0 + exp_ovun2n); - inv_exp_ovun8 = 1.0 / (1.0 + exp_ovun8); - - data->E_Un += e_un = - -p_ovun5 * (1.0 - exp_ovun6) * inv_exp_ovun2n * inv_exp_ovun8; - - CEunder1 = inv_exp_ovun2n * ( p_ovun5*p_ovun6*exp_ovun6*inv_exp_ovun8 + - p_ovun2 * e_un * exp_ovun2n); - CEunder2 = -e_un * p_ovun8 * exp_ovun8 * inv_exp_ovun8; - CEunder3 = CEunder1 * (1.0 - dfvl*workspace->dDelta_lp[i]*inv_exp_ovun1); - CEunder4 = CEunder1 * (dfvl*workspace->Delta_lp_temp[i]) * - p_ovun4 * exp_ovun1 * SQR(inv_exp_ovun1) + CEunder2; - - //fprintf( stdout, "%6d%23.15e%23.15e%23.15e\n", - // i+1, sum_ovun2, e_ov, e_un ); - - /* forces */ - workspace->CdDelta[i] += CEover3; // OvCoor - 2nd term - workspace->CdDelta[i] += CEunder3; // UnCoor - 1st term + + + for ( i = 0; i < system->N; ++i ) + { + type_i = system->atoms[i].type; + sbp_i = &(system->reaxprm.sbp[ type_i ]); + + /* over-coordination energy */ + if ( sbp_i->mass > 21.0 ) + dfvl = 0.0; + else dfvl = 1.0; // only for 1st-row elements + + p_ovun2 = sbp_i->p_ovun2; + sum_ovun1 = 0; + sum_ovun2 = 0; + + for ( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) + { + j = bonds->select.bond_list[pj].nbr; + type_j = system->atoms[j].type; + bo_ij = &(bonds->select.bond_list[pj].bo_data); + sbp_j = &(system->reaxprm.sbp[ type_j ]); + twbp = &(system->reaxprm.tbp[ type_i ][ type_j ]); + + sum_ovun1 += twbp->p_ovun1 * twbp->De_s * bo_ij->BO; + sum_ovun2 += (workspace->Delta[j] - dfvl * workspace->Delta_lp_temp[j]) * + ( bo_ij->BO_pi + bo_ij->BO_pi2 ); + + /*fprintf( stdout, "%4d%4d%23.15e%23.15e%23.15e\n", + i+1, j+1, + dfvl * workspace->Delta_lp_temp[j], + sbp_j->nlp_opt, + workspace->nlp_temp[j] );*/ + } + + exp_ovun1 = p_ovun3 * EXP( p_ovun4 * sum_ovun2 ); + inv_exp_ovun1 = 1.0 / (1 + exp_ovun1); + Delta_lpcorr = workspace->Delta[i] - + (dfvl * workspace->Delta_lp_temp[i]) * inv_exp_ovun1; + + exp_ovun2 = EXP( p_ovun2 * Delta_lpcorr ); + inv_exp_ovun2 = 1.0 / (1.0 + exp_ovun2); + + DlpVi = 1.0 / (Delta_lpcorr + sbp_i->valency + 1e-8 ); + CEover1 = Delta_lpcorr * DlpVi * inv_exp_ovun2; + + data->E_Ov += e_ov = sum_ovun1 * CEover1; + + CEover2 = sum_ovun1 * DlpVi * inv_exp_ovun2 * + ( 1.0 - Delta_lpcorr * ( DlpVi + p_ovun2 * exp_ovun2 * inv_exp_ovun2 ) ); + + CEover3 = CEover2 * (1.0 - dfvl * workspace->dDelta_lp[i] * inv_exp_ovun1 ); + + CEover4 = CEover2 * (dfvl * workspace->Delta_lp_temp[i]) * + p_ovun4 * exp_ovun1 * SQR(inv_exp_ovun1); + + + /* under-coordination potential */ + p_ovun2 = sbp_i->p_ovun2; + p_ovun5 = sbp_i->p_ovun5; + + exp_ovun2n = 1.0 / exp_ovun2; + exp_ovun6 = EXP( p_ovun6 * Delta_lpcorr ); + exp_ovun8 = p_ovun7 * EXP(p_ovun8 * sum_ovun2); + inv_exp_ovun2n = 1.0 / (1.0 + exp_ovun2n); + inv_exp_ovun8 = 1.0 / (1.0 + exp_ovun8); + + data->E_Un += e_un = + -p_ovun5 * (1.0 - exp_ovun6) * inv_exp_ovun2n * inv_exp_ovun8; + + CEunder1 = inv_exp_ovun2n * ( p_ovun5 * p_ovun6 * exp_ovun6 * inv_exp_ovun8 + + p_ovun2 * e_un * exp_ovun2n); + CEunder2 = -e_un * p_ovun8 * exp_ovun8 * inv_exp_ovun8; + CEunder3 = CEunder1 * (1.0 - dfvl * workspace->dDelta_lp[i] * inv_exp_ovun1); + CEunder4 = CEunder1 * (dfvl * workspace->Delta_lp_temp[i]) * + p_ovun4 * exp_ovun1 * SQR(inv_exp_ovun1) + CEunder2; + + //fprintf( stdout, "%6d%23.15e%23.15e%23.15e\n", + // i+1, sum_ovun2, e_ov, e_un ); + + /* forces */ + workspace->CdDelta[i] += CEover3; // OvCoor - 2nd term + workspace->CdDelta[i] += CEunder3; // UnCoor - 1st term #ifdef TEST_FORCES - Add_dDelta( system, lists, i, CEover3, workspace->f_ov ); // OvCoor - 2nd - Add_dDelta( system, lists, i, CEunder3, workspace->f_un ); // UnCoor - 1st + Add_dDelta( system, lists, i, CEover3, workspace->f_ov ); // OvCoor - 2nd + Add_dDelta( system, lists, i, CEunder3, workspace->f_un ); // UnCoor - 1st #endif - - for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ){ - pbond = &(bonds->select.bond_list[pj]); - j = pbond->nbr; - type_j = system->atoms[j].type; - bo_ij = &(pbond->bo_data); - twbp = &(system->reaxprm.tbp[ type_i ][ type_j ]); + + for ( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) + { + pbond = &(bonds->select.bond_list[pj]); + j = pbond->nbr; + type_j = system->atoms[j].type; + bo_ij = &(pbond->bo_data); + twbp = &(system->reaxprm.tbp[ type_i ][ type_j ]); - bo_ij->Cdbo += CEover1 * twbp->p_ovun1 * twbp->De_s; // OvCoor - 1st - workspace->CdDelta[j] += CEover4*(1.0 - dfvl*workspace->dDelta_lp[j])* - (bo_ij->BO_pi + bo_ij->BO_pi2); // OvCoor - 3a - bo_ij->Cdbopi += CEover4 * - (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]);//OvCoor-3b - bo_ij->Cdbopi2 += CEover4 * - (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]);//OvCoor-3b + bo_ij->Cdbo += CEover1 * twbp->p_ovun1 * twbp->De_s; // OvCoor - 1st + workspace->CdDelta[j] += CEover4 * (1.0 - dfvl * workspace->dDelta_lp[j]) * + (bo_ij->BO_pi + bo_ij->BO_pi2); // OvCoor - 3a + bo_ij->Cdbopi += CEover4 * + (workspace->Delta[j] - dfvl * workspace->Delta_lp_temp[j]); //OvCoor-3b + bo_ij->Cdbopi2 += CEover4 * + (workspace->Delta[j] - dfvl * workspace->Delta_lp_temp[j]); //OvCoor-3b - workspace->CdDelta[j] += CEunder4*(1.0-dfvl*workspace->dDelta_lp[j]) * - (bo_ij->BO_pi + bo_ij->BO_pi2); // UnCoor - 2a - bo_ij->Cdbopi += CEunder4 * - (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]);//UnCoor-2b - bo_ij->Cdbopi2 += CEunder4 * - (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]);//UnCoor-2b + workspace->CdDelta[j] += CEunder4 * (1.0 - dfvl * workspace->dDelta_lp[j]) * + (bo_ij->BO_pi + bo_ij->BO_pi2); // UnCoor - 2a + bo_ij->Cdbopi += CEunder4 * + (workspace->Delta[j] - dfvl * workspace->Delta_lp_temp[j]); //UnCoor-2b + bo_ij->Cdbopi2 += CEunder4 * + (workspace->Delta[j] - dfvl * workspace->Delta_lp_temp[j]); //UnCoor-2b #ifdef TEST_ENERGY - /* fprintf( out_control->eov, "%6d%23.15e%23.15e" - workspace->orig_id[j]+1, - //twbp->p_ovun1,twbp->De_s,Delta_lpcorr*DlpVi*inv_exp_ovun2, - CEover1*twbp->p_ovun1*twbp->De_s, CEover3 ); */ - - /*fprintf( out_control->eov, "%6d%23.15e%23.15e%23.15e%23.15e%23.15e\n", - workspace->orig_id[j]+1, - CEover4, - CEover4* - (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]), - CEover4 * (bo_ij->BO_pi + bo_ij->BO_pi2), - (1.0 - dfvl*workspace->dDelta_lp[j]), - CEover4 * (1.0 - dfvl*workspace->dDelta_lp[j]) * - (bo_ij->BO_pi + bo_ij->BO_pi2) );*/ - - /* fprintf( out_control->eun, "%6d%23.15e\n", - workspace->orig_id[j]+1, CEunder3 ); */ - - /*fprintf( out_control->eun, "%6d%23.15e%23.15e%23.15e%23.15e\n", - workspace->orig_id[j]+1, - CEunder4, - (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]), - CEunder4* - (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]), - CEunder4*(1.0 - dfvl*workspace->dDelta_lp[j])* - (bo_ij->BO_pi + bo_ij->BO_pi2) );*/ + /* fprintf( out_control->eov, "%6d%23.15e%23.15e" + workspace->orig_id[j]+1, + //twbp->p_ovun1,twbp->De_s,Delta_lpcorr*DlpVi*inv_exp_ovun2, + CEover1*twbp->p_ovun1*twbp->De_s, CEover3 ); */ + + /*fprintf( out_control->eov, "%6d%23.15e%23.15e%23.15e%23.15e%23.15e\n", + workspace->orig_id[j]+1, + CEover4, + CEover4* + (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]), + CEover4 * (bo_ij->BO_pi + bo_ij->BO_pi2), + (1.0 - dfvl*workspace->dDelta_lp[j]), + CEover4 * (1.0 - dfvl*workspace->dDelta_lp[j]) * + (bo_ij->BO_pi + bo_ij->BO_pi2) );*/ + + /* fprintf( out_control->eun, "%6d%23.15e\n", + workspace->orig_id[j]+1, CEunder3 ); */ + + /*fprintf( out_control->eun, "%6d%23.15e%23.15e%23.15e%23.15e\n", + workspace->orig_id[j]+1, + CEunder4, + (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]), + CEunder4* + (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]), + CEunder4*(1.0 - dfvl*workspace->dDelta_lp[j])* + (bo_ij->BO_pi + bo_ij->BO_pi2) );*/ #endif #ifdef TEST_FORCES - Add_dBO( system, lists, i, pj, CEover1 * twbp->p_ovun1 * twbp->De_s, - workspace->f_ov ); // OvCoor - 1st term - - Add_dDelta( system, lists, j, - CEover4 * (1.0 - dfvl*workspace->dDelta_lp[j]) * - (bo_ij->BO_pi+bo_ij->BO_pi2), workspace->f_ov );//OvCoor3a - - Add_dBOpinpi2( system, lists, i, pj, - CEover4 * (workspace->Delta[j] - - dfvl * workspace->Delta_lp_temp[j]), - CEover4 * (workspace->Delta[j] - - dfvl * workspace->Delta_lp_temp[j]), - workspace->f_ov, workspace->f_ov ); // OvCoor - 3b - - Add_dDelta( system, lists, j, - CEunder4 * (1.0 - dfvl*workspace->dDelta_lp[j]) * - (bo_ij->BO_pi + bo_ij->BO_pi2), - workspace->f_un ); // UnCoor - 2a - - Add_dBOpinpi2( system, lists, i, pj, - CEunder4 * (workspace->Delta[j] - - dfvl * workspace->Delta_lp_temp[j]), - CEunder4 * (workspace->Delta[j] - - dfvl * workspace->Delta_lp_temp[j]), - workspace->f_un, workspace->f_un ); // UnCoor - 2b + Add_dBO( system, lists, i, pj, CEover1 * twbp->p_ovun1 * twbp->De_s, + workspace->f_ov ); // OvCoor - 1st term + + Add_dDelta( system, lists, j, + CEover4 * (1.0 - dfvl * workspace->dDelta_lp[j]) * + (bo_ij->BO_pi + bo_ij->BO_pi2), workspace->f_ov ); //OvCoor3a + + Add_dBOpinpi2( system, lists, i, pj, + CEover4 * (workspace->Delta[j] - + dfvl * workspace->Delta_lp_temp[j]), + CEover4 * (workspace->Delta[j] - + dfvl * workspace->Delta_lp_temp[j]), + workspace->f_ov, workspace->f_ov ); // OvCoor - 3b + + Add_dDelta( system, lists, j, + CEunder4 * (1.0 - dfvl * workspace->dDelta_lp[j]) * + (bo_ij->BO_pi + bo_ij->BO_pi2), + workspace->f_un ); // UnCoor - 2a + + Add_dBOpinpi2( system, lists, i, pj, + CEunder4 * (workspace->Delta[j] - + dfvl * workspace->Delta_lp_temp[j]), + CEunder4 * (workspace->Delta[j] - + dfvl * workspace->Delta_lp_temp[j]), + workspace->f_un, workspace->f_un ); // UnCoor - 2b #endif - } + } -#ifdef TEST_ENERGY +#ifdef TEST_ENERGY - fprintf( out_control->eov, "%6d%15.8f%15.8f%15.8f\n", - i+1, DlpVi, Delta_lpcorr, sbp_i->valency ); + fprintf( out_control->eov, "%6d%15.8f%15.8f%15.8f\n", + i + 1, DlpVi, Delta_lpcorr, sbp_i->valency ); - fprintf( out_control->eov, "%6d%15.8f%15.8f\n", - i+1/*workspace->orig_id[i]+1*/, e_ov, data->E_Ov + data->E_Un ); + fprintf( out_control->eov, "%6d%15.8f%15.8f\n", + i + 1/*workspace->orig_id[i]+1*/, e_ov, data->E_Ov + data->E_Un ); - fprintf( out_control->eov, "%6d%15.8f%15.8f\n", - i+1/*workspace->orig_id[i]+1*/, e_un, data->E_Ov + data->E_Un ); + fprintf( out_control->eov, "%6d%15.8f%15.8f\n", + i + 1/*workspace->orig_id[i]+1*/, e_un, data->E_Ov + data->E_Un ); #endif - } + } } diff --git a/puremd_rc_1003/sPuReMD/single_body_interactions.h b/puremd_rc_1003/sPuReMD/single_body_interactions.h index a7502b83..41cc6493 100644 --- a/puremd_rc_1003/sPuReMD/single_body_interactions.h +++ b/puremd_rc_1003/sPuReMD/single_body_interactions.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -24,8 +24,7 @@ #include <mytypes.h> -void LonePair_OverUnder_Coordination_Energy( reax_system*, control_params*, - simulation_data*, static_storage*, - list**, output_controls* ); +void LonePair_OverUnder_Coordination_Energy( reax_system*, control_params*, + simulation_data*, static_storage*, + list**, output_controls* ); #endif - diff --git a/puremd_rc_1003/sPuReMD/system_props.c b/puremd_rc_1003/sPuReMD/system_props.c index 60c4f0e9..52c1d271 100644 --- a/puremd_rc_1003/sPuReMD/system_props.c +++ b/puremd_rc_1003/sPuReMD/system_props.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -26,310 +26,320 @@ real Get_Time( ) { - struct timeval tim; - - gettimeofday(&tim, NULL ); - return( tim.tv_sec + (tim.tv_usec / 1000000.0) ); + struct timeval tim; + + gettimeofday(&tim, NULL ); + return ( tim.tv_sec + (tim.tv_usec / 1000000.0) ); } real Get_Timing_Info( real t_start ) { - struct timeval tim; - real t_end; - - gettimeofday(&tim, NULL ); - t_end = tim.tv_sec + (tim.tv_usec / 1000000.0); - return (t_end - t_start); + struct timeval tim; + real t_end; + + gettimeofday(&tim, NULL ); + t_end = tim.tv_sec + (tim.tv_usec / 1000000.0); + return (t_end - t_start); } -void Temperature_Control( control_params *control, simulation_data *data, - output_controls *out_control ) +void Temperature_Control( control_params *control, simulation_data *data, + output_controls *out_control ) { - real tmp; - - if( control->T_mode == 1 ) { // step-wise temperature control - if( (data->step - data->prev_steps) % - ((int)(control->T_freq / control->dt)) == 0 ) { - if( fabs( control->T - control->T_final ) >= fabs( control->T_rate ) ) - control->T += control->T_rate; - else control->T = control->T_final; + real tmp; + + if ( control->T_mode == 1 ) // step-wise temperature control + { + if ( (data->step - data->prev_steps) % + ((int)(control->T_freq / control->dt)) == 0 ) + { + if ( fabs( control->T - control->T_final ) >= fabs( control->T_rate ) ) + control->T += control->T_rate; + else control->T = control->T_final; + } + } + else if ( control->T_mode == 2 ) // constant slope control + { + tmp = control->T_rate * control->dt / control->T_freq; + + if ( fabs( control->T - control->T_final ) >= fabs( tmp ) ) + control->T += tmp; } - } - else if( control->T_mode == 2 ) { // constant slope control - tmp = control->T_rate * control->dt / control->T_freq; - - if( fabs( control->T - control->T_final ) >= fabs( tmp ) ) - control->T += tmp; - } } void Compute_Total_Mass( reax_system *system, simulation_data *data ) { - int i; - - data->M = 0; + int i; + + data->M = 0; - for( i = 0; i < system->N; i++ ) - data->M += system->reaxprm.sbp[ system->atoms[i].type ].mass; + for ( i = 0; i < system->N; i++ ) + data->M += system->reaxprm.sbp[ system->atoms[i].type ].mass; - //fprintf ( stderr, "Compute_total_Mass -->%f<-- \n", data->M ); - data->inv_M = 1. / data->M; + //fprintf ( stderr, "Compute_total_Mass -->%f<-- \n", data->M ); + data->inv_M = 1. / data->M; } -void Compute_Center_of_Mass( reax_system *system, simulation_data *data, - FILE *fout ) +void Compute_Center_of_Mass( reax_system *system, simulation_data *data, + FILE *fout ) { - int i; - real m, xx, xy, xz, yy, yz, zz, det; - rvec tvec, diff; - rtensor mat, inv; - - rvec_MakeZero( data->xcm ); // position of CoM - rvec_MakeZero( data->vcm ); // velocity of CoM - rvec_MakeZero( data->amcm ); // angular momentum of CoM - rvec_MakeZero( data->avcm ); // angular velocity of CoM - - - /* Compute the position, velocity and angular momentum about the CoM */ - for( i = 0; i < system->N; ++i ) { - m = system->reaxprm.sbp[ system->atoms[i].type ].mass; - - rvec_ScaledAdd( data->xcm, m, system->atoms[i].x ); - rvec_ScaledAdd( data->vcm, m, system->atoms[i].v ); - - rvec_Cross( tvec, system->atoms[i].x, system->atoms[i].v ); - rvec_ScaledAdd( data->amcm, m, tvec ); - - /*fprintf( fout,"%3d %g %g %g\n", - i+1, - system->atoms[i].v[0], system->atoms[i].v[1], system->atoms[i].v[2] ); - fprintf( fout, "vcm: %g %g %g\n", - data->vcm[0], data->vcm[1], data->vcm[2] ); - */ - /* fprintf( stderr, "amcm: %12.6f %12.6f %12.6f\n", - data->amcm[0], data->amcm[1], data->amcm[2] ); */ - } - - rvec_Scale( data->xcm, data->inv_M, data->xcm ); - rvec_Scale( data->vcm, data->inv_M, data->vcm ); - - rvec_Cross( tvec, data->xcm, data->vcm ); - rvec_ScaledAdd( data->amcm, -data->M, tvec ); - - data->etran_cm = 0.5 * data->M * rvec_Norm_Sqr( data->vcm ); - - /* Calculate and then invert the inertial tensor */ - xx = xy = xz = yy = yz = zz = 0; - - for( i = 0; i < system->N; ++i ) { - m = system->reaxprm.sbp[ system->atoms[i].type ].mass; - - rvec_ScaledSum( diff, 1., system->atoms[i].x, -1., data->xcm ); - xx += diff[0] * diff[0] * m; - xy += diff[0] * diff[1] * m; - xz += diff[0] * diff[2] * m; - yy += diff[1] * diff[1] * m; - yz += diff[1] * diff[2] * m; - zz += diff[2] * diff[2] * m; - } - - mat[0][0] = yy + zz; - mat[0][1] = mat[1][0] = -xy; - mat[0][2] = mat[2][0] = -xz; - mat[1][1] = xx + zz; - mat[2][1] = mat[1][2] = -yz; - mat[2][2] = xx + yy; - - /* invert the inertial tensor */ - det = ( mat[0][0] * mat[1][1] * mat[2][2] + - mat[0][1] * mat[1][2] * mat[2][0] + - mat[0][2] * mat[1][0] * mat[2][1] ) - - ( mat[0][0] * mat[1][2] * mat[2][1] + - mat[0][1] * mat[1][0] * mat[2][2] + - mat[0][2] * mat[1][1] * mat[2][0] ); - - inv[0][0] = mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]; - inv[0][1] = mat[0][2] * mat[2][1] - mat[0][1] * mat[2][2]; - inv[0][2] = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1]; - inv[1][0] = mat[1][2] * mat[2][0] - mat[1][0] * mat[2][2]; - inv[1][1] = mat[0][0] * mat[2][2] - mat[0][2] * mat[2][0]; - inv[1][2] = mat[0][2] * mat[1][0] - mat[0][0] * mat[1][2]; - inv[2][0] = mat[1][0] * mat[2][1] - mat[2][0] * mat[1][1]; - inv[2][1] = mat[2][0] * mat[0][1] - mat[0][0] * mat[2][1]; - inv[2][2] = mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1]; - - if( fabs(det) > ALMOST_ZERO ) - rtensor_Scale( inv, 1./det, inv ); - else - rtensor_MakeZero( inv ); - - /* Compute the angular velocity about the centre of mass */ - rtensor_MatVec( data->avcm, inv, data->amcm ); - data->erot_cm = 0.5 * E_CONV * rvec_Dot( data->avcm, data->amcm ); + int i; + real m, xx, xy, xz, yy, yz, zz, det; + rvec tvec, diff; + rtensor mat, inv; + + rvec_MakeZero( data->xcm ); // position of CoM + rvec_MakeZero( data->vcm ); // velocity of CoM + rvec_MakeZero( data->amcm ); // angular momentum of CoM + rvec_MakeZero( data->avcm ); // angular velocity of CoM + + + /* Compute the position, velocity and angular momentum about the CoM */ + for ( i = 0; i < system->N; ++i ) + { + m = system->reaxprm.sbp[ system->atoms[i].type ].mass; + + rvec_ScaledAdd( data->xcm, m, system->atoms[i].x ); + rvec_ScaledAdd( data->vcm, m, system->atoms[i].v ); + + rvec_Cross( tvec, system->atoms[i].x, system->atoms[i].v ); + rvec_ScaledAdd( data->amcm, m, tvec ); + + /*fprintf( fout,"%3d %g %g %g\n", + i+1, + system->atoms[i].v[0], system->atoms[i].v[1], system->atoms[i].v[2] ); + fprintf( fout, "vcm: %g %g %g\n", + data->vcm[0], data->vcm[1], data->vcm[2] ); + */ + /* fprintf( stderr, "amcm: %12.6f %12.6f %12.6f\n", + data->amcm[0], data->amcm[1], data->amcm[2] ); */ + } + + rvec_Scale( data->xcm, data->inv_M, data->xcm ); + rvec_Scale( data->vcm, data->inv_M, data->vcm ); + + rvec_Cross( tvec, data->xcm, data->vcm ); + rvec_ScaledAdd( data->amcm, -data->M, tvec ); + + data->etran_cm = 0.5 * data->M * rvec_Norm_Sqr( data->vcm ); + + /* Calculate and then invert the inertial tensor */ + xx = xy = xz = yy = yz = zz = 0; + + for ( i = 0; i < system->N; ++i ) + { + m = system->reaxprm.sbp[ system->atoms[i].type ].mass; + + rvec_ScaledSum( diff, 1., system->atoms[i].x, -1., data->xcm ); + xx += diff[0] * diff[0] * m; + xy += diff[0] * diff[1] * m; + xz += diff[0] * diff[2] * m; + yy += diff[1] * diff[1] * m; + yz += diff[1] * diff[2] * m; + zz += diff[2] * diff[2] * m; + } + + mat[0][0] = yy + zz; + mat[0][1] = mat[1][0] = -xy; + mat[0][2] = mat[2][0] = -xz; + mat[1][1] = xx + zz; + mat[2][1] = mat[1][2] = -yz; + mat[2][2] = xx + yy; + + /* invert the inertial tensor */ + det = ( mat[0][0] * mat[1][1] * mat[2][2] + + mat[0][1] * mat[1][2] * mat[2][0] + + mat[0][2] * mat[1][0] * mat[2][1] ) - + ( mat[0][0] * mat[1][2] * mat[2][1] + + mat[0][1] * mat[1][0] * mat[2][2] + + mat[0][2] * mat[1][1] * mat[2][0] ); + + inv[0][0] = mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]; + inv[0][1] = mat[0][2] * mat[2][1] - mat[0][1] * mat[2][2]; + inv[0][2] = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1]; + inv[1][0] = mat[1][2] * mat[2][0] - mat[1][0] * mat[2][2]; + inv[1][1] = mat[0][0] * mat[2][2] - mat[0][2] * mat[2][0]; + inv[1][2] = mat[0][2] * mat[1][0] - mat[0][0] * mat[1][2]; + inv[2][0] = mat[1][0] * mat[2][1] - mat[2][0] * mat[1][1]; + inv[2][1] = mat[2][0] * mat[0][1] - mat[0][0] * mat[2][1]; + inv[2][2] = mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1]; + + if ( fabs(det) > ALMOST_ZERO ) + rtensor_Scale( inv, 1. / det, inv ); + else + rtensor_MakeZero( inv ); + + /* Compute the angular velocity about the centre of mass */ + rtensor_MatVec( data->avcm, inv, data->amcm ); + data->erot_cm = 0.5 * E_CONV * rvec_Dot( data->avcm, data->amcm ); #if defined(DEBUG) - fprintf( stderr, "xcm: %24.15e %24.15e %24.15e\n", - data->xcm[0], data->xcm[1], data->xcm[2] ); - fprintf( stderr, "vcm: %24.15e %24.15e %24.15e\n", - data->vcm[0], data->vcm[1], data->vcm[2] ); - fprintf( stderr, "amcm: %24.15e %24.15e %24.15e\n", - data->amcm[0], data->amcm[1], data->amcm[2] ); - /* fprintf( fout, "mat: %f %f %f\n %f %f %f\n %f %f %f\n", - mat[0][0], mat[0][1], mat[0][2], - mat[1][0], mat[1][1], mat[1][2], - mat[2][0], mat[2][1], mat[2][2] ); - fprintf( fout, "inv: %g %g %g\n %g %g %g\n %g %g %g\n", - inv[0][0], inv[0][1], inv[0][2], - inv[1][0], inv[1][1], inv[1][2], - inv[2][0], inv[2][1], inv[2][2] ); - fflush( fout ); */ - fprintf( stderr, "avcm: %24.15e %24.15e %24.15e\n", - data->avcm[0], data->avcm[1], data->avcm[2] ); + fprintf( stderr, "xcm: %24.15e %24.15e %24.15e\n", + data->xcm[0], data->xcm[1], data->xcm[2] ); + fprintf( stderr, "vcm: %24.15e %24.15e %24.15e\n", + data->vcm[0], data->vcm[1], data->vcm[2] ); + fprintf( stderr, "amcm: %24.15e %24.15e %24.15e\n", + data->amcm[0], data->amcm[1], data->amcm[2] ); + /* fprintf( fout, "mat: %f %f %f\n %f %f %f\n %f %f %f\n", + mat[0][0], mat[0][1], mat[0][2], + mat[1][0], mat[1][1], mat[1][2], + mat[2][0], mat[2][1], mat[2][2] ); + fprintf( fout, "inv: %g %g %g\n %g %g %g\n %g %g %g\n", + inv[0][0], inv[0][1], inv[0][2], + inv[1][0], inv[1][1], inv[1][2], + inv[2][0], inv[2][1], inv[2][2] ); + fflush( fout ); */ + fprintf( stderr, "avcm: %24.15e %24.15e %24.15e\n", + data->avcm[0], data->avcm[1], data->avcm[2] ); #endif } void Compute_Kinetic_Energy( reax_system* system, simulation_data* data ) { - int i; - rvec p; - real m; - - data->E_Kin = 0.0; - - for (i=0; i < system->N; i++) { - m = system->reaxprm.sbp[system->atoms[i].type].mass; - - rvec_Scale( p, m, system->atoms[i].v ); - data->E_Kin += 0.5 * rvec_Dot( p, system->atoms[i].v ); - - /* fprintf(stderr,"%d, %lf, %lf, %lf %lf\n", - i,system->atoms[i].v[0], system->atoms[i].v[1], system->atoms[i].v[2], - system->reaxprm.sbp[system->atoms[i].type].mass); */ - } - - data->therm.T = (2. * data->E_Kin) / (data->N_f * K_B); - - if ( fabs(data->therm.T) < ALMOST_ZERO ) /* avoid T being an absolute zero! */ - data->therm.T = ALMOST_ZERO; + int i; + rvec p; + real m; + + data->E_Kin = 0.0; + + for (i = 0; i < system->N; i++) + { + m = system->reaxprm.sbp[system->atoms[i].type].mass; + + rvec_Scale( p, m, system->atoms[i].v ); + data->E_Kin += 0.5 * rvec_Dot( p, system->atoms[i].v ); + + /* fprintf(stderr,"%d, %lf, %lf, %lf %lf\n", + i,system->atoms[i].v[0], system->atoms[i].v[1], system->atoms[i].v[2], + system->reaxprm.sbp[system->atoms[i].type].mass); */ + } + + data->therm.T = (2. * data->E_Kin) / (data->N_f * K_B); + + if ( fabs(data->therm.T) < ALMOST_ZERO ) /* avoid T being an absolute zero! */ + data->therm.T = ALMOST_ZERO; } -/* IMPORTANT: This function assumes that current kinetic energy and - * the center of mass of the system is already computed before. +/* IMPORTANT: This function assumes that current kinetic energy and + * the center of mass of the system is already computed before. * - * IMPORTANT: In Klein's paper, it is stated that a dU/dV term needs - * to be added when there are long-range interactions or long-range + * IMPORTANT: In Klein's paper, it is stated that a dU/dV term needs + * to be added when there are long-range interactions or long-range * corrections to short-range interactions present. - * We may want to add that for more accuracy. + * We may want to add that for more accuracy. */ -void Compute_Pressure_Isotropic( reax_system* system, control_params *control, - simulation_data* data, - output_controls *out_control ) +void Compute_Pressure_Isotropic( reax_system* system, control_params *control, + simulation_data* data, + output_controls *out_control ) { - int i; - reax_atom *p_atom; - rvec tx; - rvec tmp; - simulation_box *box = &(system->box); - - /* Calculate internal pressure */ - rvec_MakeZero( data->int_press ); - - // 0: both int and ext, 1: ext only, 2: int only - if( control->press_mode == 0 || control->press_mode == 2 ) { - for( i = 0; i < system->N; ++i ) { - p_atom = &( system->atoms[i] ); - - /* transform x into unitbox coordinates */ - Transform_to_UnitBox( p_atom->x, box, 1, tx ); - - /* this atom's contribution to internal pressure */ - rvec_Multiply( tmp, p_atom->f, tx ); - rvec_Add( data->int_press, tmp ); - - if( out_control->debug_level > 0 ) { - fprintf( out_control->prs, "%-8d%8.2f%8.2f%8.2f", - i+1, p_atom->x[0], p_atom->x[1], p_atom->x[2] ); - fprintf( out_control->prs, "%8.2f%8.2f%8.2f", - p_atom->f[0], p_atom->f[1], p_atom->f[2] ); - fprintf( out_control->prs, "%8.2f%8.2f%8.2f\n", - data->int_press[0],data->int_press[1],data->int_press[2]); - } + int i; + reax_atom *p_atom; + rvec tx; + rvec tmp; + simulation_box *box = &(system->box); + + /* Calculate internal pressure */ + rvec_MakeZero( data->int_press ); + + // 0: both int and ext, 1: ext only, 2: int only + if ( control->press_mode == 0 || control->press_mode == 2 ) + { + for ( i = 0; i < system->N; ++i ) + { + p_atom = &( system->atoms[i] ); + + /* transform x into unitbox coordinates */ + Transform_to_UnitBox( p_atom->x, box, 1, tx ); + + /* this atom's contribution to internal pressure */ + rvec_Multiply( tmp, p_atom->f, tx ); + rvec_Add( data->int_press, tmp ); + + if ( out_control->debug_level > 0 ) + { + fprintf( out_control->prs, "%-8d%8.2f%8.2f%8.2f", + i + 1, p_atom->x[0], p_atom->x[1], p_atom->x[2] ); + fprintf( out_control->prs, "%8.2f%8.2f%8.2f", + p_atom->f[0], p_atom->f[1], p_atom->f[2] ); + fprintf( out_control->prs, "%8.2f%8.2f%8.2f\n", + data->int_press[0], data->int_press[1], data->int_press[2]); + } + } } - } - - /* kinetic contribution */ - data->kin_press = 2. * (E_CONV * data->E_Kin) / ( 3. * box->volume * P_CONV ); - - /* Calculate total pressure in each direction */ - data->tot_press[0] = data->kin_press - - ((data->int_press[0] + data->ext_press[0]) / - (box->box_norms[1] * box->box_norms[2] * P_CONV)); - - data->tot_press[1] = data->kin_press - - ((data->int_press[1] + data->ext_press[1])/ - (box->box_norms[0] * box->box_norms[2] * P_CONV)); - - data->tot_press[2] = data->kin_press - - ((data->int_press[2] + data->ext_press[2])/ - (box->box_norms[0] * box->box_norms[1] * P_CONV)); - - /* Average pressure for the whole box */ - data->iso_bar.P=(data->tot_press[0]+data->tot_press[1]+data->tot_press[2])/3; + + /* kinetic contribution */ + data->kin_press = 2. * (E_CONV * data->E_Kin) / ( 3. * box->volume * P_CONV ); + + /* Calculate total pressure in each direction */ + data->tot_press[0] = data->kin_press - + ((data->int_press[0] + data->ext_press[0]) / + (box->box_norms[1] * box->box_norms[2] * P_CONV)); + + data->tot_press[1] = data->kin_press - + ((data->int_press[1] + data->ext_press[1]) / + (box->box_norms[0] * box->box_norms[2] * P_CONV)); + + data->tot_press[2] = data->kin_press - + ((data->int_press[2] + data->ext_press[2]) / + (box->box_norms[0] * box->box_norms[1] * P_CONV)); + + /* Average pressure for the whole box */ + data->iso_bar.P = (data->tot_press[0] + data->tot_press[1] + data->tot_press[2]) / 3; } -void Compute_Pressure_Isotropic_Klein( reax_system* system, - simulation_data* data ) +void Compute_Pressure_Isotropic_Klein( reax_system* system, + simulation_data* data ) { - int i; - reax_atom *p_atom; - rvec dx; + int i; + reax_atom *p_atom; + rvec dx; - // IMPORTANT: This function assumes that current kinetic energy and - // the center of mass of the system is already computed before. - data->iso_bar.P = 2.0 * data->E_Kin; + // IMPORTANT: This function assumes that current kinetic energy and + // the center of mass of the system is already computed before. + data->iso_bar.P = 2.0 * data->E_Kin; - for( i = 0; i < system->N; ++i ) + for ( i = 0; i < system->N; ++i ) { - p_atom = &( system->atoms[i] ); - rvec_ScaledSum(dx,1.0,p_atom->x,-1.0,data->xcm); - data->iso_bar.P += ( -F_CONV * rvec_Dot(p_atom->f, dx) ); + p_atom = &( system->atoms[i] ); + rvec_ScaledSum(dx, 1.0, p_atom->x, -1.0, data->xcm); + data->iso_bar.P += ( -F_CONV * rvec_Dot(p_atom->f, dx) ); } - data->iso_bar.P /= (3.0 * system->box.volume); + data->iso_bar.P /= (3.0 * system->box.volume); - // IMPORTANT: In Klein's paper, it is stated that a dU/dV term needs - // to be added when there are long-range interactions or long-range - // corrections to short-range interactions present. - // We may want to add that for more accuracy. + // IMPORTANT: In Klein's paper, it is stated that a dU/dV term needs + // to be added when there are long-range interactions or long-range + // corrections to short-range interactions present. + // We may want to add that for more accuracy. } -void Compute_Pressure( reax_system* system, simulation_data* data, - static_storage *workspace ) +void Compute_Pressure( reax_system* system, simulation_data* data, + static_storage *workspace ) { - int i; - reax_atom *p_atom; - rtensor temp; - - rtensor_MakeZero( data->flex_bar.P ); - - for( i = 0; i < system->N; ++i ) { - p_atom = &( system->atoms[i] ); - // Distance_on_T3_Gen( data->rcm, p_atom->x, &(system->box), &dx ); - rvec_OuterProduct( temp, p_atom->v, p_atom->v ); - rtensor_ScaledAdd( data->flex_bar.P, - system->reaxprm.sbp[ p_atom->type ].mass, temp ); - // rvec_OuterProduct(temp, workspace->virial_forces[i], p_atom->x ); - rtensor_ScaledAdd( data->flex_bar.P, -F_CONV, temp ); - } - - rtensor_Scale( data->flex_bar.P, 1.0 / system->box.volume, data->flex_bar.P ); - data->iso_bar.P = rtensor_Trace( data->flex_bar.P ) / 3.0; + int i; + reax_atom *p_atom; + rtensor temp; + + rtensor_MakeZero( data->flex_bar.P ); + + for ( i = 0; i < system->N; ++i ) + { + p_atom = &( system->atoms[i] ); + // Distance_on_T3_Gen( data->rcm, p_atom->x, &(system->box), &dx ); + rvec_OuterProduct( temp, p_atom->v, p_atom->v ); + rtensor_ScaledAdd( data->flex_bar.P, + system->reaxprm.sbp[ p_atom->type ].mass, temp ); + // rvec_OuterProduct(temp, workspace->virial_forces[i], p_atom->x ); + rtensor_ScaledAdd( data->flex_bar.P, -F_CONV, temp ); + } + + rtensor_Scale( data->flex_bar.P, 1.0 / system->box.volume, data->flex_bar.P ); + data->iso_bar.P = rtensor_Trace( data->flex_bar.P ) / 3.0; } diff --git a/puremd_rc_1003/sPuReMD/system_props.h b/puremd_rc_1003/sPuReMD/system_props.h index 0300707e..6a5ed1d9 100644 --- a/puremd_rc_1003/sPuReMD/system_props.h +++ b/puremd_rc_1003/sPuReMD/system_props.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ diff --git a/puremd_rc_1003/sPuReMD/testmd.c b/puremd_rc_1003/sPuReMD/testmd.c index 527adca0..f6e9003c 100644 --- a/puremd_rc_1003/sPuReMD/testmd.c +++ b/puremd_rc_1003/sPuReMD/testmd.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -36,94 +36,100 @@ #include "vector.h" -void Post_Evolve( reax_system* system, control_params* control, - simulation_data* data, static_storage* workspace, - list** lists, output_controls *out_control ) +void Post_Evolve( reax_system* system, control_params* control, + simulation_data* data, static_storage* workspace, + list** lists, output_controls *out_control ) { - int i; - rvec diff, cross; - - /* if velocity dependent force then - { - Generate_Neighbor_Lists( &system, &control, &lists ); - QEq(system, control, workspace, lists[FAR_NBRS]); - Introduce compute_force here if we are using velocity dependent forces - Compute_Forces(system,control,data,workspace,lists); - } */ - - /* compute kinetic energy of the system */ - Compute_Kinetic_Energy( system, data ); - - /* remove rotational and translational velocity of the center of mass */ - if( control->ensemble != NVE && - control->remove_CoM_vel && - data->step && data->step % control->remove_CoM_vel == 0 ) { - - /* compute velocity of the center of mass */ - Compute_Center_of_Mass( system, data, out_control->prs ); - - for( i = 0; i < system->N; i++ ) { - // remove translational - rvec_ScaledAdd( system->atoms[i].v, -1., data->vcm ); - - // remove rotational - rvec_ScaledSum( diff, 1., system->atoms[i].x, -1., data->xcm ); - rvec_Cross( cross, data->avcm, diff ); - rvec_ScaledAdd( system->atoms[i].v, -1., cross ); + int i; + rvec diff, cross; + + /* if velocity dependent force then + { + Generate_Neighbor_Lists( &system, &control, &lists ); + QEq(system, control, workspace, lists[FAR_NBRS]); + Introduce compute_force here if we are using velocity dependent forces + Compute_Forces(system,control,data,workspace,lists); + } */ + + /* compute kinetic energy of the system */ + Compute_Kinetic_Energy( system, data ); + + /* remove rotational and translational velocity of the center of mass */ + if ( control->ensemble != NVE && + control->remove_CoM_vel && + data->step && data->step % control->remove_CoM_vel == 0 ) + { + + /* compute velocity of the center of mass */ + Compute_Center_of_Mass( system, data, out_control->prs ); + + for ( i = 0; i < system->N; i++ ) + { + // remove translational + rvec_ScaledAdd( system->atoms[i].v, -1., data->vcm ); + + // remove rotational + rvec_ScaledSum( diff, 1., system->atoms[i].x, -1., data->xcm ); + rvec_Cross( cross, data->avcm, diff ); + rvec_ScaledAdd( system->atoms[i].v, -1., cross ); + } } - } } -void Read_System( char *geof, char *ff, char *ctrlf, - reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - output_controls *out_control ) +void Read_System( char *geof, char *ff, char *ctrlf, + reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + output_controls *out_control ) { - FILE *ffield, *ctrl; - - if ( (ffield = fopen( ff, "r" )) == NULL ) - { - fprintf( stderr, "Error opening the ffield file!\n" ); - exit( FILE_NOT_FOUND_ERR ); - } - if ( (ctrl = fopen( ctrlf, "r" )) == NULL ) - { - fprintf( stderr, "Error opening the ffield file!\n" ); - exit( FILE_NOT_FOUND_ERR ); - } - - /* ffield file */ - Read_Force_Field( ffield, &(system->reaxprm) ); - - /* control file */ - Read_Control_File( ctrl, system, control, out_control ); - - /* geo file */ - if( control->geo_format == XYZ ) { - fprintf( stderr, "xyz input is not implemented yet\n" ); - exit(1); - } - else if( control->geo_format == PDB ) - Read_PDB( geof, system, control, data, workspace ); - else if( control->geo_format == BGF ) - Read_BGF( geof, system, control, data, workspace ); - else if( control->geo_format == ASCII_RESTART ) { - Read_ASCII_Restart( geof, system, control, data, workspace ); - control->restart = 1; - } - else if( control->geo_format == BINARY_RESTART ) { - Read_Binary_Restart( geof, system, control, data, workspace ); - control->restart = 1; - } - else { - fprintf( stderr, "unknown geo file format. terminating!\n" ); - exit(1); - } + FILE *ffield, *ctrl; + + if ( (ffield = fopen( ff, "r" )) == NULL ) + { + fprintf( stderr, "Error opening the ffield file!\n" ); + exit( FILE_NOT_FOUND_ERR ); + } + if ( (ctrl = fopen( ctrlf, "r" )) == NULL ) + { + fprintf( stderr, "Error opening the ffield file!\n" ); + exit( FILE_NOT_FOUND_ERR ); + } + + /* ffield file */ + Read_Force_Field( ffield, &(system->reaxprm) ); + + /* control file */ + Read_Control_File( ctrl, system, control, out_control ); + + /* geo file */ + if ( control->geo_format == XYZ ) + { + fprintf( stderr, "xyz input is not implemented yet\n" ); + exit(1); + } + else if ( control->geo_format == PDB ) + Read_PDB( geof, system, control, data, workspace ); + else if ( control->geo_format == BGF ) + Read_BGF( geof, system, control, data, workspace ); + else if ( control->geo_format == ASCII_RESTART ) + { + Read_ASCII_Restart( geof, system, control, data, workspace ); + control->restart = 1; + } + else if ( control->geo_format == BINARY_RESTART ) + { + Read_Binary_Restart( geof, system, control, data, workspace ); + control->restart = 1; + } + else + { + fprintf( stderr, "unknown geo file format. terminating!\n" ); + exit(1); + } #if defined(DEBUG_FOCUS) - fprintf( stderr, "input files have been read...\n" ); - Print_Box_Information( &(system->box), stderr ); + fprintf( stderr, "input files have been read...\n" ); + Print_Box_Information( &(system->box), stderr ); #endif } @@ -136,67 +142,69 @@ static void usage(char* argv[]) int main(int argc, char* argv[]) { - reax_system system; - control_params control; - simulation_data data; - static_storage workspace; - list *lists; - output_controls out_control; - evolve_function Evolve; - int steps; - - if( argc != 4 ) - { - usage(argv); - exit( INVALID_INPUT ); - } - - lists = (list*) malloc( sizeof(list) * LIST_N ); - - Read_System( argv[1], argv[2], argv[3], &system, &control, - &data, &workspace, &out_control ); - - Initialize( &system, &control, &data, &workspace, &lists, - &out_control, &Evolve ); - - /* compute f_0 */ - //if( control.restart == 0 ) { - Reset( &system, &control, &data, &workspace, &lists ); - Generate_Neighbor_Lists( &system, &control, &data, &workspace, - &lists, &out_control ); - - //fprintf( stderr, "total: %.2f secs\n", data.timing.nbrs); - Compute_Forces(&system, &control, &data, &workspace, &lists, &out_control); - Compute_Kinetic_Energy( &system, &data ); - Output_Results(&system, &control, &data, &workspace, &lists, &out_control); - ++data.step; - //} - // - - - for( ; data.step <= control.nsteps; data.step++ ) { - if( control.T_mode ) - Temperature_Control( &control, &data, &out_control ); - Evolve( &system, &control, &data, &workspace, &lists, &out_control ); - Post_Evolve( &system, &control, &data, &workspace, &lists, &out_control ); + reax_system system; + control_params control; + simulation_data data; + static_storage workspace; + list *lists; + output_controls out_control; + evolve_function Evolve; + int steps; + + if ( argc != 4 ) + { + usage(argv); + exit( INVALID_INPUT ); + } + + lists = (list*) malloc( sizeof(list) * LIST_N ); + + Read_System( argv[1], argv[2], argv[3], &system, &control, + &data, &workspace, &out_control ); + + Initialize( &system, &control, &data, &workspace, &lists, + &out_control, &Evolve ); + + /* compute f_0 */ + //if( control.restart == 0 ) { + Reset( &system, &control, &data, &workspace, &lists ); + Generate_Neighbor_Lists( &system, &control, &data, &workspace, + &lists, &out_control ); + + //fprintf( stderr, "total: %.2f secs\n", data.timing.nbrs); + Compute_Forces(&system, &control, &data, &workspace, &lists, &out_control); + Compute_Kinetic_Energy( &system, &data ); Output_Results(&system, &control, &data, &workspace, &lists, &out_control); - Analysis( &system, &control, &data, &workspace, &lists, &out_control ); - - steps = data.step - data.prev_steps; - if( steps && out_control.restart_freq && - steps % out_control.restart_freq == 0 ) - Write_Restart( &system, &control, &data, &workspace, &out_control ); - } - - if( out_control.write_steps > 0 ) { - fclose( out_control.trj ); - Write_PDB( &system, &control, &data, &workspace, - &(lists[BONDS]), &out_control ); - } - - data.timing.end = Get_Time( ); - data.timing.elapsed = Get_Timing_Info( data.timing.start ); - fprintf( out_control.log, "total: %.2f secs\n", data.timing.elapsed ); - - return 0; + ++data.step; + //} + // + + + for ( ; data.step <= control.nsteps; data.step++ ) + { + if ( control.T_mode ) + Temperature_Control( &control, &data, &out_control ); + Evolve( &system, &control, &data, &workspace, &lists, &out_control ); + Post_Evolve( &system, &control, &data, &workspace, &lists, &out_control ); + Output_Results(&system, &control, &data, &workspace, &lists, &out_control); + Analysis( &system, &control, &data, &workspace, &lists, &out_control ); + + steps = data.step - data.prev_steps; + if ( steps && out_control.restart_freq && + steps % out_control.restart_freq == 0 ) + Write_Restart( &system, &control, &data, &workspace, &out_control ); + } + + if ( out_control.write_steps > 0 ) + { + fclose( out_control.trj ); + Write_PDB( &system, &control, &data, &workspace, + &(lists[BONDS]), &out_control ); + } + + data.timing.end = Get_Time( ); + data.timing.elapsed = Get_Timing_Info( data.timing.start ); + fprintf( out_control.log, "total: %.2f secs\n", data.timing.elapsed ); + + return 0; } diff --git a/puremd_rc_1003/sPuReMD/three_body_interactions.c b/puremd_rc_1003/sPuReMD/three_body_interactions.c index 317571bf..9aef73d4 100644 --- a/puremd_rc_1003/sPuReMD/three_body_interactions.c +++ b/puremd_rc_1003/sPuReMD/three_body_interactions.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -27,750 +27,777 @@ /* calculates the theta angle between i-j-k */ -void Calculate_Theta( rvec dvec_ji, real d_ji, rvec dvec_jk, real d_jk, - real *theta, real *cos_theta ) +void Calculate_Theta( rvec dvec_ji, real d_ji, rvec dvec_jk, real d_jk, + real *theta, real *cos_theta ) { - (*cos_theta) = Dot( dvec_ji, dvec_jk, 3 ) / ( d_ji * d_jk ); - if( *cos_theta > 1. ) *cos_theta = 1.0; - if( *cos_theta < -1. ) *cos_theta = -1.0; + (*cos_theta) = Dot( dvec_ji, dvec_jk, 3 ) / ( d_ji * d_jk ); + if ( *cos_theta > 1. ) *cos_theta = 1.0; + if ( *cos_theta < -1. ) *cos_theta = -1.0; - (*theta) = ACOS( *cos_theta ); + (*theta) = ACOS( *cos_theta ); } /* calculates the derivative of the cosine of the angle between i-j-k */ -void Calculate_dCos_Theta( rvec dvec_ji, real d_ji, rvec dvec_jk, real d_jk, - rvec* dcos_theta_di, rvec* dcos_theta_dj, - rvec* dcos_theta_dk ) +void Calculate_dCos_Theta( rvec dvec_ji, real d_ji, rvec dvec_jk, real d_jk, + rvec* dcos_theta_di, rvec* dcos_theta_dj, + rvec* dcos_theta_dk ) { - int t; - real sqr_d_ji = SQR(d_ji); - real sqr_d_jk = SQR(d_jk); - real inv_dists = 1.0 / (d_ji * d_jk); - real inv_dists3 = POW( inv_dists, 3 ); - real dot_dvecs = Dot( dvec_ji, dvec_jk, 3 ); - real Cdot_inv3 = dot_dvecs * inv_dists3; - - for( t = 0; t < 3; ++t ) { - (*dcos_theta_di)[t] = dvec_jk[t] * inv_dists - - Cdot_inv3 * sqr_d_jk * dvec_ji[t]; - - (*dcos_theta_dj)[t] = -(dvec_jk[t] + dvec_ji[t]) * inv_dists + - Cdot_inv3 * ( sqr_d_jk * dvec_ji[t] + sqr_d_ji * dvec_jk[t] ); - - (*dcos_theta_dk)[t] = dvec_ji[t] * inv_dists - - Cdot_inv3 * sqr_d_ji * dvec_jk[t]; - } - - /*fprintf( stderr, - "%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e\n", - dvec_jk[t] * inv_dists*/ + int t; + real sqr_d_ji = SQR(d_ji); + real sqr_d_jk = SQR(d_jk); + real inv_dists = 1.0 / (d_ji * d_jk); + real inv_dists3 = POW( inv_dists, 3 ); + real dot_dvecs = Dot( dvec_ji, dvec_jk, 3 ); + real Cdot_inv3 = dot_dvecs * inv_dists3; + + for ( t = 0; t < 3; ++t ) + { + (*dcos_theta_di)[t] = dvec_jk[t] * inv_dists - + Cdot_inv3 * sqr_d_jk * dvec_ji[t]; + + (*dcos_theta_dj)[t] = -(dvec_jk[t] + dvec_ji[t]) * inv_dists + + Cdot_inv3 * ( sqr_d_jk * dvec_ji[t] + sqr_d_ji * dvec_jk[t] ); + + (*dcos_theta_dk)[t] = dvec_ji[t] * inv_dists - + Cdot_inv3 * sqr_d_ji * dvec_jk[t]; + } + + /*fprintf( stderr, + "%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e\n", + dvec_jk[t] * inv_dists*/ } -/* this is a 3-body interaction in which the main role is +/* this is a 3-body interaction in which the main role is played by j which sits in the middle of the other two. */ -void Three_Body_Interactions( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Three_Body_Interactions( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i, j, pi, k, pk, t; - int type_i, type_j, type_k; - int start_j, end_j, start_pk, end_pk; - int flag, cnt, num_thb_intrs; - - real temp, temp_bo_jt, pBOjt7; - real p_val1, p_val2, p_val3, p_val4, p_val5; - real p_val6, p_val7, p_val8, p_val9, p_val10; - real p_pen1, p_pen2, p_pen3, p_pen4; - real p_coa1, p_coa2, p_coa3, p_coa4; - real trm8, expval6, expval7, expval2theta, expval12theta, exp3ij, exp3jk; - real exp_pen2ij, exp_pen2jk, exp_pen3, exp_pen4, trm_pen34, exp_coa2; - real dSBO1, dSBO2, SBO, SBO2, CSBO2, SBOp, prod_SBO; - real CEval1, CEval2, CEval3, CEval4, CEval5, CEval6, CEval7, CEval8; - real CEpen1, CEpen2, CEpen3; - real e_ang, e_coa, e_pen; - real CEcoa1, CEcoa2, CEcoa3, CEcoa4, CEcoa5; - real Cf7ij, Cf7jk, Cf8j, Cf9j; - real f7_ij, f7_jk, f8_Dj, f9_Dj; - real Ctheta_0, theta_0, theta_00, theta, cos_theta, sin_theta; - real r_ij, r_jk; - real BOA_ij, BOA_jk; - real vlpadj; - rvec force, ext_press; - // rtensor temp_rtensor, total_rtensor; - real *total_bo; - three_body_header *thbh; - three_body_parameters *thbp; - three_body_interaction_data *p_ijk, *p_kji; - bond_data *pbond_ij, *pbond_jk, *pbond_jt; - bond_order_data *bo_ij, *bo_jk, *bo_jt; - list *bonds, *thb_intrs; - bond_data *bond_list; - three_body_interaction_data *thb_list; - - total_bo = workspace->total_bond_order; - bonds = (*lists) + BONDS; - bond_list = bonds->select.bond_list; - thb_intrs = (*lists) + THREE_BODIES; - thb_list = thb_intrs->select.three_body_list; - - /* global parameters used in these calculations */ - p_val6 = system->reaxprm.gp.l[14]; - p_val8 = system->reaxprm.gp.l[33]; - p_val9 = system->reaxprm.gp.l[16]; - p_val10 = system->reaxprm.gp.l[17]; - num_thb_intrs = 0; - - for( j = 0; j < system->N; ++j ) { - // fprintf( out_control->eval, "j: %d\n", j ); - type_j = system->atoms[j].type; - start_j = Start_Index(j, bonds); - end_j = End_Index(j, bonds); - - p_val3 = system->reaxprm.sbp[ type_j ].p_val3; - p_val5 = system->reaxprm.sbp[ type_j ].p_val5; - - SBOp = 0, prod_SBO = 1; - for( t = start_j; t < end_j; ++t ) { - bo_jt = &(bond_list[t].bo_data); - SBOp += (bo_jt->BO_pi + bo_jt->BO_pi2); - temp = SQR( bo_jt->BO ); - temp *= temp; - temp *= temp; - prod_SBO *= EXP( -temp ); - } - - /* modifications to match Adri's code - 09/01/09 */ - if( workspace->vlpex[j] >= 0 ){ - vlpadj = 0; - dSBO2 = prod_SBO - 1; - } - else{ - vlpadj = workspace->nlp[j]; - dSBO2 = (prod_SBO - 1) * (1 - p_val8 * workspace->dDelta_lp[j]); - } + int i, j, pi, k, pk, t; + int type_i, type_j, type_k; + int start_j, end_j, start_pk, end_pk; + int flag, cnt, num_thb_intrs; - SBO = SBOp + (1 - prod_SBO) * (-workspace->Delta_boc[j] - p_val8 * vlpadj); - dSBO1 = -8 * prod_SBO * ( workspace->Delta_boc[j] + p_val8 * vlpadj ); + real temp, temp_bo_jt, pBOjt7; + real p_val1, p_val2, p_val3, p_val4, p_val5; + real p_val6, p_val7, p_val8, p_val9, p_val10; + real p_pen1, p_pen2, p_pen3, p_pen4; + real p_coa1, p_coa2, p_coa3, p_coa4; + real trm8, expval6, expval7, expval2theta, expval12theta, exp3ij, exp3jk; + real exp_pen2ij, exp_pen2jk, exp_pen3, exp_pen4, trm_pen34, exp_coa2; + real dSBO1, dSBO2, SBO, SBO2, CSBO2, SBOp, prod_SBO; + real CEval1, CEval2, CEval3, CEval4, CEval5, CEval6, CEval7, CEval8; + real CEpen1, CEpen2, CEpen3; + real e_ang, e_coa, e_pen; + real CEcoa1, CEcoa2, CEcoa3, CEcoa4, CEcoa5; + real Cf7ij, Cf7jk, Cf8j, Cf9j; + real f7_ij, f7_jk, f8_Dj, f9_Dj; + real Ctheta_0, theta_0, theta_00, theta, cos_theta, sin_theta; + real r_ij, r_jk; + real BOA_ij, BOA_jk; + real vlpadj; + rvec force, ext_press; + // rtensor temp_rtensor, total_rtensor; + real *total_bo; + three_body_header *thbh; + three_body_parameters *thbp; + three_body_interaction_data *p_ijk, *p_kji; + bond_data *pbond_ij, *pbond_jk, *pbond_jt; + bond_order_data *bo_ij, *bo_jk, *bo_jt; + list *bonds, *thb_intrs; + bond_data *bond_list; + three_body_interaction_data *thb_list; + + total_bo = workspace->total_bond_order; + bonds = (*lists) + BONDS; + bond_list = bonds->select.bond_list; + thb_intrs = (*lists) + THREE_BODIES; + thb_list = thb_intrs->select.three_body_list; + + /* global parameters used in these calculations */ + p_val6 = system->reaxprm.gp.l[14]; + p_val8 = system->reaxprm.gp.l[33]; + p_val9 = system->reaxprm.gp.l[16]; + p_val10 = system->reaxprm.gp.l[17]; + num_thb_intrs = 0; + + for ( j = 0; j < system->N; ++j ) + { + // fprintf( out_control->eval, "j: %d\n", j ); + type_j = system->atoms[j].type; + start_j = Start_Index(j, bonds); + end_j = End_Index(j, bonds); + + p_val3 = system->reaxprm.sbp[ type_j ].p_val3; + p_val5 = system->reaxprm.sbp[ type_j ].p_val5; + + SBOp = 0, prod_SBO = 1; + for ( t = start_j; t < end_j; ++t ) + { + bo_jt = &(bond_list[t].bo_data); + SBOp += (bo_jt->BO_pi + bo_jt->BO_pi2); + temp = SQR( bo_jt->BO ); + temp *= temp; + temp *= temp; + prod_SBO *= EXP( -temp ); + } + + /* modifications to match Adri's code - 09/01/09 */ + if ( workspace->vlpex[j] >= 0 ) + { + vlpadj = 0; + dSBO2 = prod_SBO - 1; + } + else + { + vlpadj = workspace->nlp[j]; + dSBO2 = (prod_SBO - 1) * (1 - p_val8 * workspace->dDelta_lp[j]); + } + + SBO = SBOp + (1 - prod_SBO) * (-workspace->Delta_boc[j] - p_val8 * vlpadj); + dSBO1 = -8 * prod_SBO * ( workspace->Delta_boc[j] + p_val8 * vlpadj ); + + if ( SBO <= 0 ) + SBO2 = 0, CSBO2 = 0; + else if ( SBO > 0 && SBO <= 1 ) + { + SBO2 = POW( SBO, p_val9 ); + CSBO2 = p_val9 * POW( SBO, p_val9 - 1 ); + } + else if ( SBO > 1 && SBO < 2 ) + { + SBO2 = 2 - POW( 2 - SBO, p_val9 ); + CSBO2 = p_val9 * POW( 2 - SBO, p_val9 - 1 ); + } + else + SBO2 = 2, CSBO2 = 0; + + expval6 = EXP( p_val6 * workspace->Delta_boc[j] ); + + /* unlike 2-body intrs where we enforce i<j, we cannot put any such + restrictions here. such a restriction would prevent us from producing + all 4-body intrs correctly */ + for ( pi = start_j; pi < end_j; ++pi ) + { + Set_Start_Index( pi, num_thb_intrs, thb_intrs ); + pbond_ij = &(bond_list[pi]); + bo_ij = &(pbond_ij->bo_data); + BOA_ij = bo_ij->BO - control->thb_cut; + + + if ( BOA_ij/*bo_ij->BO*/ > 0.0 ) + { + i = pbond_ij->nbr; + r_ij = pbond_ij->d; + type_i = system->atoms[i].type; + // fprintf( out_control->eval, "i: %d\n", i ); + + + /* first copy 3-body intrs from previously computed ones where i>k. + IMPORTANT: if it is less costly to compute theta and its + derivative, we should definitely re-compute them, + instead of copying! + in the second for-loop below, we compute only new 3-body intrs + where i < k */ + for ( pk = start_j; pk < pi; ++pk ) + { + // fprintf( out_control->eval, "pk: %d\n", pk ); + start_pk = Start_Index( pk, thb_intrs ); + end_pk = End_Index( pk, thb_intrs ); + + for ( t = start_pk; t < end_pk; ++t ) + if ( thb_list[t].thb == i ) + { + p_ijk = &(thb_list[num_thb_intrs]); + p_kji = &(thb_list[t]); + + p_ijk->thb = bond_list[pk].nbr; + p_ijk->pthb = pk; + p_ijk->theta = p_kji->theta; + rvec_Copy( p_ijk->dcos_di, p_kji->dcos_dk ); + rvec_Copy( p_ijk->dcos_dj, p_kji->dcos_dj ); + rvec_Copy( p_ijk->dcos_dk, p_kji->dcos_di ); + + ++num_thb_intrs; + break; + } + } + + + /* and this is the second for loop mentioned above */ + for ( pk = pi + 1; pk < end_j; ++pk ) + { + pbond_jk = &(bond_list[pk]); + bo_jk = &(pbond_jk->bo_data); + BOA_jk = bo_jk->BO - control->thb_cut; + k = pbond_jk->nbr; + type_k = system->atoms[k].type; + p_ijk = &( thb_list[num_thb_intrs] ); + + //CHANGE ORIGINAL + if (BOA_jk <= 0) continue; + //CHANGE ORIGINAL + + + Calculate_Theta( pbond_ij->dvec, pbond_ij->d, + pbond_jk->dvec, pbond_jk->d, + &theta, &cos_theta ); + + Calculate_dCos_Theta( pbond_ij->dvec, pbond_ij->d, + pbond_jk->dvec, pbond_jk->d, + &(p_ijk->dcos_di), &(p_ijk->dcos_dj), + &(p_ijk->dcos_dk) ); + + p_ijk->thb = k; + p_ijk->pthb = pk; + p_ijk->theta = theta; + + sin_theta = SIN( theta ); + if ( sin_theta < 1.0e-5 ) + sin_theta = 1.0e-5; + + ++num_thb_intrs; + + + if ( BOA_jk > 0.0 && + (bo_ij->BO * bo_jk->BO) > SQR(control->thb_cut)/*0*/) + { + r_jk = pbond_jk->d; + thbh = &( system->reaxprm.thbp[type_i][type_j][type_k] ); + flag = 0; + + /* if( workspace->orig_id[i] < workspace->orig_id[k] ) + fprintf( stdout, "%6d %6d %6d %7.3f %7.3f %7.3f\n", + workspace->orig_id[i], workspace->orig_id[j], + workspace->orig_id[k], bo_ij->BO, bo_jk->BO, p_ijk->theta ); + else + fprintf( stdout, "%6d %6d %6d %7.3f %7.3f %7.3f\n", + workspace->orig_id[k], workspace->orig_id[j], + workspace->orig_id[i], bo_jk->BO, bo_ij->BO, p_ijk->theta ); */ + + + for ( cnt = 0; cnt < thbh->cnt; ++cnt ) + { + // fprintf( out_control->eval, + // "%6d%6d%6d -- exists in thbp\n", i+1, j+1, k+1 ); + + if ( fabs(thbh->prm[cnt].p_val1) > 0.001 ) + { + thbp = &( thbh->prm[cnt] ); + + /* ANGLE ENERGY */ + p_val1 = thbp->p_val1; + p_val2 = thbp->p_val2; + p_val4 = thbp->p_val4; + p_val7 = thbp->p_val7; + theta_00 = thbp->theta_00; + + exp3ij = EXP( -p_val3 * POW( BOA_ij, p_val4 ) ); + f7_ij = 1.0 - exp3ij; + Cf7ij = p_val3 * p_val4 * + POW( BOA_ij, p_val4 - 1.0 ) * exp3ij; + + exp3jk = EXP( -p_val3 * POW( BOA_jk, p_val4 ) ); + f7_jk = 1.0 - exp3jk; + Cf7jk = p_val3 * p_val4 * + POW( BOA_jk, p_val4 - 1.0 ) * exp3jk; + + expval7 = EXP( -p_val7 * workspace->Delta_boc[j] ); + trm8 = 1.0 + expval6 + expval7; + f8_Dj = p_val5 - ( (p_val5 - 1.0) * (2.0 + expval6) / trm8 ); + Cf8j = ( (1.0 - p_val5) / SQR(trm8) ) * + (p_val6 * expval6 * trm8 - + (2.0 + expval6) * ( p_val6 * expval6 - p_val7 * expval7 )); + + theta_0 = 180.0 - + theta_00 * (1.0 - EXP(-p_val10 * (2.0 - SBO2))); + theta_0 = DEG2RAD( theta_0 ); + + expval2theta = EXP(-p_val2 * SQR(theta_0 - theta)); + if ( p_val1 >= 0 ) + expval12theta = p_val1 * (1.0 - expval2theta); + else // To avoid linear Me-H-Me angles (6/6/06) + expval12theta = p_val1 * -expval2theta; + + CEval1 = Cf7ij * f7_jk * f8_Dj * expval12theta; + CEval2 = Cf7jk * f7_ij * f8_Dj * expval12theta; + CEval3 = Cf8j * f7_ij * f7_jk * expval12theta; + CEval4 = -2.0 * p_val1 * p_val2 * f7_ij * f7_jk * f8_Dj * + expval2theta * (theta_0 - theta); + + Ctheta_0 = p_val10 * DEG2RAD(theta_00) * + exp( -p_val10 * (2.0 - SBO2) ); + + CEval5 = -CEval4 * Ctheta_0 * CSBO2; + CEval6 = CEval5 * dSBO1; + CEval7 = CEval5 * dSBO2; + CEval8 = -CEval4 / sin_theta; + + data->E_Ang += e_ang = f7_ij * f7_jk * f8_Dj * expval12theta; + /* END ANGLE ENERGY*/ + + + /* PENALTY ENERGY */ + p_pen1 = thbp->p_pen1; + p_pen2 = system->reaxprm.gp.l[19]; + p_pen3 = system->reaxprm.gp.l[20]; + p_pen4 = system->reaxprm.gp.l[21]; + + exp_pen2ij = EXP( -p_pen2 * SQR( BOA_ij - 2.0 ) ); + exp_pen2jk = EXP( -p_pen2 * SQR( BOA_jk - 2.0 ) ); + exp_pen3 = EXP( -p_pen3 * workspace->Delta[j] ); + exp_pen4 = EXP( p_pen4 * workspace->Delta[j] ); + trm_pen34 = 1.0 + exp_pen3 + exp_pen4; + f9_Dj = ( 2.0 + exp_pen3 ) / trm_pen34; + Cf9j = (-p_pen3 * exp_pen3 * trm_pen34 - + (2.0 + exp_pen3) * ( -p_pen3 * exp_pen3 + + p_pen4 * exp_pen4 )) / + SQR( trm_pen34 ); + + data->E_Pen += e_pen = + p_pen1 * f9_Dj * exp_pen2ij * exp_pen2jk; + + CEpen1 = e_pen * Cf9j / f9_Dj; + temp = -2.0 * p_pen2 * e_pen; + CEpen2 = temp * (BOA_ij - 2.0); + CEpen3 = temp * (BOA_jk - 2.0); + /* END PENALTY ENERGY */ + + + /* COALITION ENERGY */ + p_coa1 = thbp->p_coa1; + p_coa2 = system->reaxprm.gp.l[2]; + p_coa3 = system->reaxprm.gp.l[38]; + p_coa4 = system->reaxprm.gp.l[30]; + + exp_coa2 = EXP( p_coa2 * workspace->Delta_boc[j] ); + data->E_Coa += e_coa = + p_coa1 / (1. + exp_coa2) * + EXP( -p_coa3 * SQR(total_bo[i] - BOA_ij) ) * + EXP( -p_coa3 * SQR(total_bo[k] - BOA_jk) ) * + EXP( -p_coa4 * SQR(BOA_ij - 1.5) ) * + EXP( -p_coa4 * SQR(BOA_jk - 1.5) ); + + CEcoa1 = -2 * p_coa4 * (BOA_ij - 1.5) * e_coa; + CEcoa2 = -2 * p_coa4 * (BOA_jk - 1.5) * e_coa; + CEcoa3 = -p_coa2 * exp_coa2 * e_coa / (1 + exp_coa2); + CEcoa4 = -2 * p_coa3 * (total_bo[i] - BOA_ij) * e_coa; + CEcoa5 = -2 * p_coa3 * (total_bo[k] - BOA_jk) * e_coa; + /* END COALITION ENERGY */ + + /* FORCES */ + bo_ij->Cdbo += (CEval1 + CEpen2 + (CEcoa1 - CEcoa4)); + bo_jk->Cdbo += (CEval2 + CEpen3 + (CEcoa2 - CEcoa5)); + workspace->CdDelta[j] += ((CEval3 + CEval7) + + CEpen1 + CEcoa3); + workspace->CdDelta[i] += CEcoa4; + workspace->CdDelta[k] += CEcoa5; + + for ( t = start_j; t < end_j; ++t ) + { + pbond_jt = &( bond_list[t] ); + bo_jt = &(pbond_jt->bo_data); + temp_bo_jt = bo_jt->BO; + temp = CUBE( temp_bo_jt ); + pBOjt7 = temp * temp * temp_bo_jt; + + // fprintf( out_control->eval, "%6d%12.8f\n", + // workspace->orig_id[ bond_list[t].nbr ], + // (CEval6 * pBOjt7) ); + + bo_jt->Cdbo += (CEval6 * pBOjt7); + bo_jt->Cdbopi += CEval5; + bo_jt->Cdbopi2 += CEval5; + } + + + if ( control->ensemble == NVE || control->ensemble == NVT || control->ensemble == bNVT) + { + rvec_ScaledAdd( system->atoms[i].f, CEval8, p_ijk->dcos_di ); + rvec_ScaledAdd( system->atoms[j].f, CEval8, p_ijk->dcos_dj ); + rvec_ScaledAdd( system->atoms[k].f, CEval8, p_ijk->dcos_dk ); + } + else + { + /* terms not related to bond order derivatives + are added directly into + forces and pressure vector/tensor */ + rvec_Scale( force, CEval8, p_ijk->dcos_di ); + rvec_Add( system->atoms[i].f, force ); + rvec_iMultiply( ext_press, pbond_ij->rel_box, force ); + rvec_Add( data->ext_press, ext_press ); + + rvec_ScaledAdd( system->atoms[j].f, + CEval8, p_ijk->dcos_dj ); + + rvec_Scale( force, CEval8, p_ijk->dcos_dk ); + rvec_Add( system->atoms[k].f, force ); + rvec_iMultiply( ext_press, pbond_jk->rel_box, force ); + rvec_Add( data->ext_press, ext_press ); + + + /* This part is for a fully-flexible box */ + /* rvec_OuterProduct( temp_rtensor, + p_ijk->dcos_di, system->atoms[i].x ); + rtensor_Scale( total_rtensor, +CEval8, temp_rtensor ); + + rvec_OuterProduct( temp_rtensor, + p_ijk->dcos_dj, system->atoms[j].x ); + rtensor_ScaledAdd(total_rtensor, CEval8, temp_rtensor); + + rvec_OuterProduct( temp_rtensor, + p_ijk->dcos_dk, system->atoms[k].x ); + rtensor_ScaledAdd(total_rtensor, CEval8, temp_rtensor); + + if( pbond_ij->imaginary || pbond_jk->imaginary ) + rtensor_ScaledAdd( data->flex_bar.P, + -1.0, total_rtensor ); + else + rtensor_Add( data->flex_bar.P, total_rtensor ); */ + } - if( SBO <= 0 ) - SBO2 = 0, CSBO2 = 0; - else if( SBO > 0 && SBO <= 1 ) { - SBO2 = POW( SBO, p_val9 ); - CSBO2 = p_val9 * POW( SBO, p_val9 - 1 ); - } - else if( SBO > 1 && SBO < 2 ) { - SBO2 = 2 - POW( 2-SBO, p_val9 ); - CSBO2 = p_val9 * POW( 2 - SBO, p_val9 - 1 ); - } - else - SBO2 = 2, CSBO2 = 0; - - expval6 = EXP( p_val6 * workspace->Delta_boc[j] ); - - /* unlike 2-body intrs where we enforce i<j, we cannot put any such - restrictions here. such a restriction would prevent us from producing - all 4-body intrs correctly */ - for( pi = start_j; pi < end_j; ++pi ) { - Set_Start_Index( pi, num_thb_intrs, thb_intrs ); - pbond_ij = &(bond_list[pi]); - bo_ij = &(pbond_ij->bo_data); - BOA_ij = bo_ij->BO - control->thb_cut; - - - if( BOA_ij/*bo_ij->BO*/ > 0.0 ) { - i = pbond_ij->nbr; - r_ij = pbond_ij->d; - type_i = system->atoms[i].type; - // fprintf( out_control->eval, "i: %d\n", i ); - - - /* first copy 3-body intrs from previously computed ones where i>k. - IMPORTANT: if it is less costly to compute theta and its - derivative, we should definitely re-compute them, - instead of copying! - in the second for-loop below, we compute only new 3-body intrs - where i < k */ - for( pk = start_j; pk < pi; ++pk ) { - // fprintf( out_control->eval, "pk: %d\n", pk ); - start_pk = Start_Index( pk, thb_intrs ); - end_pk = End_Index( pk, thb_intrs ); - - for( t = start_pk; t < end_pk; ++t ) - if( thb_list[t].thb == i ) { - p_ijk = &(thb_list[num_thb_intrs]); - p_kji = &(thb_list[t]); - - p_ijk->thb = bond_list[pk].nbr; - p_ijk->pthb = pk; - p_ijk->theta = p_kji->theta; - rvec_Copy( p_ijk->dcos_di, p_kji->dcos_dk ); - rvec_Copy( p_ijk->dcos_dj, p_kji->dcos_dj ); - rvec_Copy( p_ijk->dcos_dk, p_kji->dcos_di ); - - ++num_thb_intrs; - break; - } - } - - - /* and this is the second for loop mentioned above */ - for( pk = pi+1; pk < end_j; ++pk ) { - pbond_jk = &(bond_list[pk]); - bo_jk = &(pbond_jk->bo_data); - BOA_jk = bo_jk->BO - control->thb_cut; - k = pbond_jk->nbr; - type_k = system->atoms[k].type; - p_ijk = &( thb_list[num_thb_intrs] ); - - //CHANGE ORIGINAL - if (BOA_jk <= 0) continue; - //CHANGE ORIGINAL - - - Calculate_Theta( pbond_ij->dvec, pbond_ij->d, - pbond_jk->dvec, pbond_jk->d, - &theta, &cos_theta ); - - Calculate_dCos_Theta( pbond_ij->dvec, pbond_ij->d, - pbond_jk->dvec, pbond_jk->d, - &(p_ijk->dcos_di), &(p_ijk->dcos_dj), - &(p_ijk->dcos_dk) ); - - p_ijk->thb = k; - p_ijk->pthb = pk; - p_ijk->theta = theta; - - sin_theta = SIN( theta ); - if( sin_theta < 1.0e-5 ) - sin_theta = 1.0e-5; - - ++num_thb_intrs; - - - if( BOA_jk > 0.0 && - (bo_ij->BO * bo_jk->BO) > SQR(control->thb_cut)/*0*/) { - r_jk = pbond_jk->d; - thbh = &( system->reaxprm.thbp[type_i][type_j][type_k] ); - flag = 0; - - /* if( workspace->orig_id[i] < workspace->orig_id[k] ) - fprintf( stdout, "%6d %6d %6d %7.3f %7.3f %7.3f\n", - workspace->orig_id[i], workspace->orig_id[j], - workspace->orig_id[k], bo_ij->BO, bo_jk->BO, p_ijk->theta ); - else - fprintf( stdout, "%6d %6d %6d %7.3f %7.3f %7.3f\n", - workspace->orig_id[k], workspace->orig_id[j], - workspace->orig_id[i], bo_jk->BO, bo_ij->BO, p_ijk->theta ); */ - - - for( cnt = 0; cnt < thbh->cnt; ++cnt ) { - // fprintf( out_control->eval, - // "%6d%6d%6d -- exists in thbp\n", i+1, j+1, k+1 ); - - if( fabs(thbh->prm[cnt].p_val1) > 0.001 ) { - thbp = &( thbh->prm[cnt] ); - - /* ANGLE ENERGY */ - p_val1 = thbp->p_val1; - p_val2 = thbp->p_val2; - p_val4 = thbp->p_val4; - p_val7 = thbp->p_val7; - theta_00 = thbp->theta_00; - - exp3ij = EXP( -p_val3 * POW( BOA_ij, p_val4 ) ); - f7_ij = 1.0 - exp3ij; - Cf7ij = p_val3 * p_val4 * - POW( BOA_ij, p_val4 - 1.0 ) * exp3ij; - - exp3jk = EXP( -p_val3 * POW( BOA_jk, p_val4 ) ); - f7_jk = 1.0 - exp3jk; - Cf7jk = p_val3 * p_val4 * - POW( BOA_jk, p_val4 - 1.0 ) * exp3jk; - - expval7 = EXP( -p_val7 * workspace->Delta_boc[j] ); - trm8 = 1.0 + expval6 + expval7; - f8_Dj = p_val5 - ( (p_val5 - 1.0) * (2.0 + expval6) / trm8 ); - Cf8j = ( (1.0 - p_val5) / SQR(trm8) ) * - (p_val6 * expval6 * trm8 - - (2.0 + expval6) * ( p_val6 * expval6 - p_val7 * expval7 )); - - theta_0 = 180.0 - - theta_00 * (1.0 - EXP(-p_val10 * (2.0 - SBO2))); - theta_0 = DEG2RAD( theta_0 ); - - expval2theta = EXP(-p_val2 * SQR(theta_0-theta)); - if( p_val1 >= 0 ) - expval12theta = p_val1 * (1.0 - expval2theta); - else // To avoid linear Me-H-Me angles (6/6/06) - expval12theta = p_val1 * -expval2theta; - - CEval1 = Cf7ij * f7_jk * f8_Dj * expval12theta; - CEval2 = Cf7jk * f7_ij * f8_Dj * expval12theta; - CEval3 = Cf8j * f7_ij * f7_jk * expval12theta; - CEval4 = -2.0 * p_val1 * p_val2 * f7_ij * f7_jk * f8_Dj * - expval2theta * (theta_0 - theta); - - Ctheta_0 = p_val10 * DEG2RAD(theta_00) * - exp( -p_val10 * (2.0 - SBO2) ); - - CEval5 = -CEval4 * Ctheta_0 * CSBO2; - CEval6 = CEval5 * dSBO1; - CEval7 = CEval5 * dSBO2; - CEval8 = -CEval4 / sin_theta; - - data->E_Ang += e_ang = f7_ij * f7_jk * f8_Dj * expval12theta; - /* END ANGLE ENERGY*/ - - - /* PENALTY ENERGY */ - p_pen1 = thbp->p_pen1; - p_pen2 = system->reaxprm.gp.l[19]; - p_pen3 = system->reaxprm.gp.l[20]; - p_pen4 = system->reaxprm.gp.l[21]; - - exp_pen2ij = EXP( -p_pen2 * SQR( BOA_ij - 2.0 ) ); - exp_pen2jk = EXP( -p_pen2 * SQR( BOA_jk - 2.0 ) ); - exp_pen3 = EXP( -p_pen3 * workspace->Delta[j] ); - exp_pen4 = EXP( p_pen4 * workspace->Delta[j] ); - trm_pen34 = 1.0 + exp_pen3 + exp_pen4; - f9_Dj = ( 2.0 + exp_pen3 ) / trm_pen34; - Cf9j = (-p_pen3 * exp_pen3 * trm_pen34 - - (2.0 + exp_pen3) * ( -p_pen3 * exp_pen3 + - p_pen4 * exp_pen4 )) / - SQR( trm_pen34 ); - - data->E_Pen += e_pen = - p_pen1 * f9_Dj * exp_pen2ij * exp_pen2jk; - - CEpen1 = e_pen * Cf9j / f9_Dj; - temp = -2.0 * p_pen2 * e_pen; - CEpen2 = temp * (BOA_ij - 2.0); - CEpen3 = temp * (BOA_jk - 2.0); - /* END PENALTY ENERGY */ - - - /* COALITION ENERGY */ - p_coa1 = thbp->p_coa1; - p_coa2 = system->reaxprm.gp.l[2]; - p_coa3 = system->reaxprm.gp.l[38]; - p_coa4 = system->reaxprm.gp.l[30]; - - exp_coa2 = EXP( p_coa2 * workspace->Delta_boc[j] ); - data->E_Coa += e_coa = - p_coa1 / (1. + exp_coa2) * - EXP( -p_coa3 * SQR(total_bo[i] - BOA_ij) ) * - EXP( -p_coa3 * SQR(total_bo[k] - BOA_jk) ) * - EXP( -p_coa4 * SQR(BOA_ij - 1.5) ) * - EXP( -p_coa4 * SQR(BOA_jk - 1.5) ); - - CEcoa1 = -2 * p_coa4 * (BOA_ij - 1.5) * e_coa; - CEcoa2 = -2 * p_coa4 * (BOA_jk - 1.5) * e_coa; - CEcoa3 = -p_coa2 * exp_coa2 * e_coa / (1+exp_coa2); - CEcoa4 = -2*p_coa3 * (total_bo[i]-BOA_ij) * e_coa; - CEcoa5 = -2*p_coa3 * (total_bo[k]-BOA_jk) * e_coa; - /* END COALITION ENERGY */ - - /* FORCES */ - bo_ij->Cdbo += (CEval1 + CEpen2 + (CEcoa1-CEcoa4)); - bo_jk->Cdbo += (CEval2 + CEpen3 + (CEcoa2-CEcoa5)); - workspace->CdDelta[j] += ((CEval3 + CEval7) + - CEpen1 + CEcoa3); - workspace->CdDelta[i] += CEcoa4; - workspace->CdDelta[k] += CEcoa5; - - for( t = start_j; t < end_j; ++t ) { - pbond_jt = &( bond_list[t] ); - bo_jt = &(pbond_jt->bo_data); - temp_bo_jt = bo_jt->BO; - temp = CUBE( temp_bo_jt ); - pBOjt7 = temp * temp * temp_bo_jt; - - // fprintf( out_control->eval, "%6d%12.8f\n", - // workspace->orig_id[ bond_list[t].nbr ], - // (CEval6 * pBOjt7) ); - - bo_jt->Cdbo += (CEval6 * pBOjt7); - bo_jt->Cdbopi += CEval5; - bo_jt->Cdbopi2 += CEval5; - } - - - if( control->ensemble == NVE || control->ensemble == NVT || control->ensemble == bNVT) { - rvec_ScaledAdd( system->atoms[i].f, CEval8, p_ijk->dcos_di ); - rvec_ScaledAdd( system->atoms[j].f, CEval8, p_ijk->dcos_dj ); - rvec_ScaledAdd( system->atoms[k].f, CEval8, p_ijk->dcos_dk ); - } - else { - /* terms not related to bond order derivatives - are added directly into - forces and pressure vector/tensor */ - rvec_Scale( force, CEval8, p_ijk->dcos_di ); - rvec_Add( system->atoms[i].f, force ); - rvec_iMultiply( ext_press, pbond_ij->rel_box, force ); - rvec_Add( data->ext_press, ext_press ); - - rvec_ScaledAdd( system->atoms[j].f, - CEval8, p_ijk->dcos_dj ); - - rvec_Scale( force, CEval8, p_ijk->dcos_dk ); - rvec_Add( system->atoms[k].f, force ); - rvec_iMultiply( ext_press, pbond_jk->rel_box, force ); - rvec_Add( data->ext_press, ext_press ); - - - /* This part is for a fully-flexible box */ - /* rvec_OuterProduct( temp_rtensor, - p_ijk->dcos_di, system->atoms[i].x ); - rtensor_Scale( total_rtensor, +CEval8, temp_rtensor ); - - rvec_OuterProduct( temp_rtensor, - p_ijk->dcos_dj, system->atoms[j].x ); - rtensor_ScaledAdd(total_rtensor, CEval8, temp_rtensor); - - rvec_OuterProduct( temp_rtensor, - p_ijk->dcos_dk, system->atoms[k].x ); - rtensor_ScaledAdd(total_rtensor, CEval8, temp_rtensor); - - if( pbond_ij->imaginary || pbond_jk->imaginary ) - rtensor_ScaledAdd( data->flex_bar.P, - -1.0, total_rtensor ); - else - rtensor_Add( data->flex_bar.P, total_rtensor ); */ - } - #ifdef TEST_ENERGY - fprintf( out_control->eval, - //"%6d%6d%6d%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e", - "%6d%6d%6d%23.15e%23.15e%23.15e\n", - i+1, j+1, k+1, - //workspace->orig_id[i]+1, - //workspace->orig_id[j]+1, - //workspace->orig_id[k]+1, - //workspace->Delta_boc[j], - RAD2DEG(theta), /*BOA_ij, BOA_jk, */ - e_ang, data->E_Ang ); - - /*fprintf( out_control->eval, - "%23.15e%23.15e%23.15e%23.15e", - p_val3, p_val4, BOA_ij, BOA_jk ); - fprintf( out_control->eval, - "%23.15e%23.15e%23.15e%23.15e", - f7_ij, f7_jk, f8_Dj, expval12theta ); - fprintf( out_control->eval, - "%23.15e%23.15e%23.15e%23.15e%23.15e\n", - CEval1, CEval2, CEval3, CEval4, CEval5 - //CEval6, CEval7, CEval8 );*/ - - /*fprintf( out_control->eval, - "%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e\n", - -p_ijk->dcos_di[0]/sin_theta, - -p_ijk->dcos_di[1]/sin_theta, - -p_ijk->dcos_di[2]/sin_theta, - -p_ijk->dcos_dj[0]/sin_theta, - -p_ijk->dcos_dj[1]/sin_theta, - -p_ijk->dcos_dj[2]/sin_theta, - -p_ijk->dcos_dk[0]/sin_theta, - -p_ijk->dcos_dk[1]/sin_theta, - -p_ijk->dcos_dk[2]/sin_theta );*/ - - /* fprintf( out_control->epen, - "%23.15e%23.15e%23.15e\n", - CEpen1, CEpen2, CEpen3 ); - fprintf( out_control->epen, - "%6d%6d%6d%23.15e%23.15e%23.15e%23.15e%23.15e\n", - workspace->orig_id[i], workspace->orig_id[j], - workspace->orig_id[k], RAD2DEG(theta), - BOA_ij, BOA_jk, e_pen, data->E_Pen ); */ - - fprintf( out_control->ecoa, - "%6d%6d%6d%23.15e%23.15e%23.15e%23.15e%23.15e\n", - workspace->orig_id[i], - workspace->orig_id[j], - workspace->orig_id[k], - RAD2DEG(theta), BOA_ij, BOA_jk, - e_coa, data->E_Coa ); + fprintf( out_control->eval, + //"%6d%6d%6d%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e", + "%6d%6d%6d%23.15e%23.15e%23.15e\n", + i + 1, j + 1, k + 1, + //workspace->orig_id[i]+1, + //workspace->orig_id[j]+1, + //workspace->orig_id[k]+1, + //workspace->Delta_boc[j], + RAD2DEG(theta), /*BOA_ij, BOA_jk, */ + e_ang, data->E_Ang ); + + /*fprintf( out_control->eval, + "%23.15e%23.15e%23.15e%23.15e", + p_val3, p_val4, BOA_ij, BOA_jk ); + fprintf( out_control->eval, + "%23.15e%23.15e%23.15e%23.15e", + f7_ij, f7_jk, f8_Dj, expval12theta ); + fprintf( out_control->eval, + "%23.15e%23.15e%23.15e%23.15e%23.15e\n", + CEval1, CEval2, CEval3, CEval4, CEval5 + //CEval6, CEval7, CEval8 );*/ + + /*fprintf( out_control->eval, + "%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e\n", + -p_ijk->dcos_di[0]/sin_theta, + -p_ijk->dcos_di[1]/sin_theta, + -p_ijk->dcos_di[2]/sin_theta, + -p_ijk->dcos_dj[0]/sin_theta, + -p_ijk->dcos_dj[1]/sin_theta, + -p_ijk->dcos_dj[2]/sin_theta, + -p_ijk->dcos_dk[0]/sin_theta, + -p_ijk->dcos_dk[1]/sin_theta, + -p_ijk->dcos_dk[2]/sin_theta );*/ + + /* fprintf( out_control->epen, + "%23.15e%23.15e%23.15e\n", + CEpen1, CEpen2, CEpen3 ); + fprintf( out_control->epen, + "%6d%6d%6d%23.15e%23.15e%23.15e%23.15e%23.15e\n", + workspace->orig_id[i], workspace->orig_id[j], + workspace->orig_id[k], RAD2DEG(theta), + BOA_ij, BOA_jk, e_pen, data->E_Pen ); */ + + fprintf( out_control->ecoa, + "%6d%6d%6d%23.15e%23.15e%23.15e%23.15e%23.15e\n", + workspace->orig_id[i], + workspace->orig_id[j], + workspace->orig_id[k], + RAD2DEG(theta), BOA_ij, BOA_jk, + e_coa, data->E_Coa ); #endif - + #ifdef TEST_FORCES /* angle forces */ - Add_dBO( system, lists, j, pi, CEval1, workspace->f_ang ); - Add_dBO( system, lists, j, pk, CEval2, workspace->f_ang ); - Add_dDelta( system, lists, - j, CEval3 + CEval7, workspace->f_ang ); - - for( t = start_j; t < end_j; ++t ) { - pbond_jt = &( bond_list[t] ); - bo_jt = &(pbond_jt->bo_data); - temp_bo_jt = bo_jt->BO; - temp = CUBE( temp_bo_jt ); - pBOjt7 = temp * temp * temp_bo_jt; - - Add_dBO( system, lists, j, t, pBOjt7 * CEval6, - workspace->f_ang ); - Add_dBOpinpi2( system, lists, j, t, - CEval5, CEval5, - workspace->f_ang, workspace->f_ang ); - } - - rvec_ScaledAdd( workspace->f_ang[i], CEval8, p_ijk->dcos_di ); - rvec_ScaledAdd( workspace->f_ang[j], CEval8, p_ijk->dcos_dj ); - rvec_ScaledAdd( workspace->f_ang[k], CEval8, p_ijk->dcos_dk ); - /* end angle forces */ - - /* penalty forces */ - Add_dDelta( system, lists, j, CEpen1, workspace->f_pen ); - Add_dBO( system, lists, j, pi, CEpen2, workspace->f_pen ); - Add_dBO( system, lists, j, pk, CEpen3, workspace->f_pen ); - /* end penalty forces */ - - /* coalition forces */ - Add_dBO( system, lists, - j, pi, CEcoa1-CEcoa4, workspace->f_coa ); - Add_dBO( system, lists, - j, pk, CEcoa2-CEcoa5, workspace->f_coa ); - Add_dDelta( system, lists, j, CEcoa3, workspace->f_coa ); - Add_dDelta( system, lists, i, CEcoa4, workspace->f_coa ); - Add_dDelta( system, lists, k, CEcoa5, workspace->f_coa ); - /* end coalition forces */ + Add_dBO( system, lists, j, pi, CEval1, workspace->f_ang ); + Add_dBO( system, lists, j, pk, CEval2, workspace->f_ang ); + Add_dDelta( system, lists, + j, CEval3 + CEval7, workspace->f_ang ); + + for ( t = start_j; t < end_j; ++t ) + { + pbond_jt = &( bond_list[t] ); + bo_jt = &(pbond_jt->bo_data); + temp_bo_jt = bo_jt->BO; + temp = CUBE( temp_bo_jt ); + pBOjt7 = temp * temp * temp_bo_jt; + + Add_dBO( system, lists, j, t, pBOjt7 * CEval6, + workspace->f_ang ); + Add_dBOpinpi2( system, lists, j, t, + CEval5, CEval5, + workspace->f_ang, workspace->f_ang ); + } + + rvec_ScaledAdd( workspace->f_ang[i], CEval8, p_ijk->dcos_di ); + rvec_ScaledAdd( workspace->f_ang[j], CEval8, p_ijk->dcos_dj ); + rvec_ScaledAdd( workspace->f_ang[k], CEval8, p_ijk->dcos_dk ); + /* end angle forces */ + + /* penalty forces */ + Add_dDelta( system, lists, j, CEpen1, workspace->f_pen ); + Add_dBO( system, lists, j, pi, CEpen2, workspace->f_pen ); + Add_dBO( system, lists, j, pk, CEpen3, workspace->f_pen ); + /* end penalty forces */ + + /* coalition forces */ + Add_dBO( system, lists, + j, pi, CEcoa1 - CEcoa4, workspace->f_coa ); + Add_dBO( system, lists, + j, pk, CEcoa2 - CEcoa5, workspace->f_coa ); + Add_dDelta( system, lists, j, CEcoa3, workspace->f_coa ); + Add_dDelta( system, lists, i, CEcoa4, workspace->f_coa ); + Add_dDelta( system, lists, k, CEcoa5, workspace->f_coa ); + /* end coalition forces */ #endif - } - } - } - } - } - - Set_End_Index(pi, num_thb_intrs, thb_intrs ); + } + } + } + } + } + + Set_End_Index(pi, num_thb_intrs, thb_intrs ); + } } - } - - - if( num_thb_intrs >= thb_intrs->num_intrs * DANGER_ZONE ) { - workspace->realloc.num_3body = num_thb_intrs; - if( num_thb_intrs > thb_intrs->num_intrs ) { - fprintf( stderr, "step%d-ran out of space on angle_list: top=%d, max=%d", - data->step, num_thb_intrs, thb_intrs->num_intrs ); - exit( INSUFFICIENT_SPACE ); + + + if ( num_thb_intrs >= thb_intrs->num_intrs * DANGER_ZONE ) + { + workspace->realloc.num_3body = num_thb_intrs; + if ( num_thb_intrs > thb_intrs->num_intrs ) + { + fprintf( stderr, "step%d-ran out of space on angle_list: top=%d, max=%d", + data->step, num_thb_intrs, thb_intrs->num_intrs ); + exit( INSUFFICIENT_SPACE ); + } } - } - - //fprintf( stderr,"%d: Number of angle interactions: %d\n", - // data->step, num_thb_intrs ); + + //fprintf( stderr,"%d: Number of angle interactions: %d\n", + // data->step, num_thb_intrs ); #ifdef TEST_ENERGY - fprintf( stderr,"Number of angle interactions: %d\n", num_thb_intrs ); - - fprintf( stderr,"Angle Energy:%g\t Penalty Energy:%g\t Coalition Energy:%g\n", - data->E_Ang, data->E_Pen, data->E_Coa ); - - fprintf( stderr,"3body: ext_press (%23.15e %23.15e %23.15e)\n", - data->ext_press[0], data->ext_press[1], data->ext_press[2] ); + fprintf( stderr, "Number of angle interactions: %d\n", num_thb_intrs ); + + fprintf( stderr, "Angle Energy:%g\t Penalty Energy:%g\t Coalition Energy:%g\n", + data->E_Ang, data->E_Pen, data->E_Coa ); + + fprintf( stderr, "3body: ext_press (%23.15e %23.15e %23.15e)\n", + data->ext_press[0], data->ext_press[1], data->ext_press[2] ); #endif } -void Hydrogen_Bonds( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Hydrogen_Bonds( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i, j, k, pi, pk, itr, top; - int type_i, type_j, type_k; - int start_j, end_j, hb_start_j, hb_end_j; - int hblist[MAX_BONDS]; - int num_hb_intrs = 0; - real r_ij, r_jk, theta, cos_theta, sin_xhz4, cos_xhz1, sin_theta2; - real e_hb, exp_hb2, exp_hb3, CEhb1, CEhb2, CEhb3; - rvec dcos_theta_di, dcos_theta_dj, dcos_theta_dk; - rvec dvec_jk, force, ext_press; - ivec rel_jk; - // rtensor temp_rtensor, total_rtensor; - hbond_parameters *hbp; - bond_order_data *bo_ij; - bond_data *pbond_ij; - far_neighbor_data *nbr_jk; - list *bonds, *hbonds; - bond_data *bond_list; - hbond_data *hbond_list; - - bonds = (*lists) + BONDS; - bond_list = bonds->select.bond_list; - - hbonds = (*lists) + HBONDS; - hbond_list = hbonds->select.hbond_list; - - /* loops below discover the Hydrogen bonds between i-j-k triplets. - here j is H atom and there has to be some bond between i and j. - Hydrogen bond is between j and k. - so in this function i->X, j->H, k->Z when we map - variables onto the ones in the handout.*/ - for( j = 0; j < system->N; ++j ) - if( system->reaxprm.sbp[system->atoms[j].type].p_hbond==1 ) {// j must be H - /*set j's variables */ - type_j = system->atoms[j].type; - start_j = Start_Index(j, bonds); - end_j = End_Index(j, bonds); - hb_start_j = Start_Index( workspace->hbond_index[j], hbonds ); - hb_end_j = End_Index ( workspace->hbond_index[j], hbonds ); - - top = 0; - for( pi = start_j; pi < end_j; ++pi ) { - pbond_ij = &( bond_list[pi] ); - i = pbond_ij->nbr; - bo_ij = &(pbond_ij->bo_data); - type_i = system->atoms[i].type; - - if( system->reaxprm.sbp[type_i].p_hbond == 2 && - bo_ij->BO >= HB_THRESHOLD ) - hblist[top++] = pi; - } - - // fprintf( stderr, "j: %d, top: %d, hb_start_j: %d, hb_end_j:%d\n", - // j, top, hb_start_j, hb_end_j ); - - for( pk = hb_start_j; pk < hb_end_j; ++pk ) { - /* set k's varibles */ - k = hbond_list[pk].nbr; - type_k = system->atoms[k].type; - nbr_jk = hbond_list[pk].ptr; - r_jk = nbr_jk->d; - rvec_Scale( dvec_jk, hbond_list[pk].scl, nbr_jk->dvec ); - - for( itr=0; itr < top; ++itr ) { - pi = hblist[itr]; - pbond_ij = &( bond_list[pi] ); - i = pbond_ij->nbr; - - if( i != k ) { - bo_ij = &(pbond_ij->bo_data); - type_i = system->atoms[i].type; - r_ij = pbond_ij->d; - hbp = &(system->reaxprm.hbp[ type_i ][ type_j ][ type_k ]); - ++num_hb_intrs; - - Calculate_Theta( pbond_ij->dvec, pbond_ij->d, dvec_jk, r_jk, - &theta, &cos_theta ); - /* the derivative of cos(theta) */ - Calculate_dCos_Theta( pbond_ij->dvec, pbond_ij->d, dvec_jk, r_jk, - &dcos_theta_di, &dcos_theta_dj, - &dcos_theta_dk ); - - /* hydrogen bond energy*/ - sin_theta2 = SIN( theta/2.0 ); - sin_xhz4 = SQR(sin_theta2); - sin_xhz4 *= sin_xhz4; - cos_xhz1 = ( 1.0 - cos_theta ); - exp_hb2 = EXP( -hbp->p_hb2 * bo_ij->BO ); - exp_hb3 = EXP( -hbp->p_hb3 * ( hbp->r0_hb / r_jk + - r_jk / hbp->r0_hb - 2.0 ) ); - - data->E_HB += e_hb = - hbp->p_hb1 * (1.0 - exp_hb2) * exp_hb3 * sin_xhz4; - - CEhb1 = hbp->p_hb1*hbp->p_hb2 * exp_hb2*exp_hb3 * sin_xhz4; - CEhb2 = -hbp->p_hb1/2.0*(1.0 - exp_hb2) * exp_hb3 * cos_xhz1; - CEhb3 = -hbp->p_hb3 * e_hb * (-hbp->r0_hb / SQR(r_jk) + - 1.0 / hbp->r0_hb); - - /* hydrogen bond forces */ - bo_ij->Cdbo += CEhb1; // dbo term - - if( control->ensemble == NVE || control->ensemble == NVT || control->ensemble == bNVT) { - rvec_ScaledAdd( system->atoms[i].f, - +CEhb2, dcos_theta_di ); //dcos terms - rvec_ScaledAdd( system->atoms[j].f, - +CEhb2, dcos_theta_dj ); - rvec_ScaledAdd( system->atoms[k].f, - +CEhb2, dcos_theta_dk ); - //dr terms - rvec_ScaledAdd( system->atoms[j].f, -CEhb3/r_jk, dvec_jk ); - rvec_ScaledAdd( system->atoms[k].f, +CEhb3/r_jk, dvec_jk ); - } - else - { - /* for pressure coupling, terms that are not related - to bond order derivatives are added directly into - pressure vector/tensor */ - rvec_Scale( force, +CEhb2, dcos_theta_di ); // dcos terms - rvec_Add( system->atoms[i].f, force ); - rvec_iMultiply( ext_press, pbond_ij->rel_box, force ); - rvec_ScaledAdd( data->ext_press, 1.0, ext_press ); - - rvec_ScaledAdd( system->atoms[j].f, +CEhb2, dcos_theta_dj ); - - ivec_Scale( rel_jk, hbond_list[pk].scl, nbr_jk->rel_box ); - rvec_Scale( force, +CEhb2, dcos_theta_dk ); - rvec_Add( system->atoms[k].f, force ); - rvec_iMultiply( ext_press, rel_jk, force ); - rvec_ScaledAdd( data->ext_press, 1.0, ext_press ); - - //dr terms - rvec_ScaledAdd( system->atoms[j].f, -CEhb3/r_jk, dvec_jk ); - - rvec_Scale( force, CEhb3/r_jk, dvec_jk ); - rvec_Add( system->atoms[k].f, force ); - rvec_iMultiply( ext_press, rel_jk, force ); - rvec_ScaledAdd( data->ext_press, 1.0, ext_press ); - - /* This part is intended for a fully-flexible box */ - /* rvec_OuterProduct( temp_rtensor, - dcos_theta_di, system->atoms[i].x ); - rtensor_Scale( total_rtensor, -CEhb2, temp_rtensor ); - - rvec_ScaledSum( temp_rvec, -CEhb2, dcos_theta_dj, - -CEhb3/r_jk, pbond_jk->dvec ); - rvec_OuterProduct( temp_rtensor, - temp_rvec, system->atoms[j].x ); - rtensor_Add( total_rtensor, temp_rtensor ); - - rvec_ScaledSum( temp_rvec, -CEhb2, dcos_theta_dk, - +CEhb3/r_jk, pbond_jk->dvec ); - rvec_OuterProduct( temp_rtensor, - temp_rvec, system->atoms[k].x ); - rtensor_Add( total_rtensor, temp_rtensor ); - - if( pbond_ij->imaginary || pbond_jk->imaginary ) - rtensor_ScaledAdd( data->flex_bar.P, -1.0, total_rtensor ); - else - rtensor_Add( data->flex_bar.P, total_rtensor ); */ - } - + int i, j, k, pi, pk, itr, top; + int type_i, type_j, type_k; + int start_j, end_j, hb_start_j, hb_end_j; + int hblist[MAX_BONDS]; + int num_hb_intrs = 0; + real r_ij, r_jk, theta, cos_theta, sin_xhz4, cos_xhz1, sin_theta2; + real e_hb, exp_hb2, exp_hb3, CEhb1, CEhb2, CEhb3; + rvec dcos_theta_di, dcos_theta_dj, dcos_theta_dk; + rvec dvec_jk, force, ext_press; + ivec rel_jk; + // rtensor temp_rtensor, total_rtensor; + hbond_parameters *hbp; + bond_order_data *bo_ij; + bond_data *pbond_ij; + far_neighbor_data *nbr_jk; + list *bonds, *hbonds; + bond_data *bond_list; + hbond_data *hbond_list; + + bonds = (*lists) + BONDS; + bond_list = bonds->select.bond_list; + + hbonds = (*lists) + HBONDS; + hbond_list = hbonds->select.hbond_list; + + /* loops below discover the Hydrogen bonds between i-j-k triplets. + here j is H atom and there has to be some bond between i and j. + Hydrogen bond is between j and k. + so in this function i->X, j->H, k->Z when we map + variables onto the ones in the handout.*/ + for ( j = 0; j < system->N; ++j ) + if ( system->reaxprm.sbp[system->atoms[j].type].p_hbond == 1 ) // j must be H + { + /*set j's variables */ + type_j = system->atoms[j].type; + start_j = Start_Index(j, bonds); + end_j = End_Index(j, bonds); + hb_start_j = Start_Index( workspace->hbond_index[j], hbonds ); + hb_end_j = End_Index ( workspace->hbond_index[j], hbonds ); + + top = 0; + for ( pi = start_j; pi < end_j; ++pi ) + { + pbond_ij = &( bond_list[pi] ); + i = pbond_ij->nbr; + bo_ij = &(pbond_ij->bo_data); + type_i = system->atoms[i].type; + + if ( system->reaxprm.sbp[type_i].p_hbond == 2 && + bo_ij->BO >= HB_THRESHOLD ) + hblist[top++] = pi; + } + + // fprintf( stderr, "j: %d, top: %d, hb_start_j: %d, hb_end_j:%d\n", + // j, top, hb_start_j, hb_end_j ); + + for ( pk = hb_start_j; pk < hb_end_j; ++pk ) + { + /* set k's varibles */ + k = hbond_list[pk].nbr; + type_k = system->atoms[k].type; + nbr_jk = hbond_list[pk].ptr; + r_jk = nbr_jk->d; + rvec_Scale( dvec_jk, hbond_list[pk].scl, nbr_jk->dvec ); + + for ( itr = 0; itr < top; ++itr ) + { + pi = hblist[itr]; + pbond_ij = &( bond_list[pi] ); + i = pbond_ij->nbr; + + if ( i != k ) + { + bo_ij = &(pbond_ij->bo_data); + type_i = system->atoms[i].type; + r_ij = pbond_ij->d; + hbp = &(system->reaxprm.hbp[ type_i ][ type_j ][ type_k ]); + ++num_hb_intrs; + + Calculate_Theta( pbond_ij->dvec, pbond_ij->d, dvec_jk, r_jk, + &theta, &cos_theta ); + /* the derivative of cos(theta) */ + Calculate_dCos_Theta( pbond_ij->dvec, pbond_ij->d, dvec_jk, r_jk, + &dcos_theta_di, &dcos_theta_dj, + &dcos_theta_dk ); + + /* hydrogen bond energy*/ + sin_theta2 = SIN( theta / 2.0 ); + sin_xhz4 = SQR(sin_theta2); + sin_xhz4 *= sin_xhz4; + cos_xhz1 = ( 1.0 - cos_theta ); + exp_hb2 = EXP( -hbp->p_hb2 * bo_ij->BO ); + exp_hb3 = EXP( -hbp->p_hb3 * ( hbp->r0_hb / r_jk + + r_jk / hbp->r0_hb - 2.0 ) ); + + data->E_HB += e_hb = + hbp->p_hb1 * (1.0 - exp_hb2) * exp_hb3 * sin_xhz4; + + CEhb1 = hbp->p_hb1 * hbp->p_hb2 * exp_hb2 * exp_hb3 * sin_xhz4; + CEhb2 = -hbp->p_hb1 / 2.0 * (1.0 - exp_hb2) * exp_hb3 * cos_xhz1; + CEhb3 = -hbp->p_hb3 * e_hb * (-hbp->r0_hb / SQR(r_jk) + + 1.0 / hbp->r0_hb); + + /* hydrogen bond forces */ + bo_ij->Cdbo += CEhb1; // dbo term + + if ( control->ensemble == NVE || control->ensemble == NVT || control->ensemble == bNVT) + { + rvec_ScaledAdd( system->atoms[i].f, + +CEhb2, dcos_theta_di ); //dcos terms + rvec_ScaledAdd( system->atoms[j].f, + +CEhb2, dcos_theta_dj ); + rvec_ScaledAdd( system->atoms[k].f, + +CEhb2, dcos_theta_dk ); + //dr terms + rvec_ScaledAdd( system->atoms[j].f, -CEhb3 / r_jk, dvec_jk ); + rvec_ScaledAdd( system->atoms[k].f, +CEhb3 / r_jk, dvec_jk ); + } + else + { + /* for pressure coupling, terms that are not related + to bond order derivatives are added directly into + pressure vector/tensor */ + rvec_Scale( force, +CEhb2, dcos_theta_di ); // dcos terms + rvec_Add( system->atoms[i].f, force ); + rvec_iMultiply( ext_press, pbond_ij->rel_box, force ); + rvec_ScaledAdd( data->ext_press, 1.0, ext_press ); + + rvec_ScaledAdd( system->atoms[j].f, +CEhb2, dcos_theta_dj ); + + ivec_Scale( rel_jk, hbond_list[pk].scl, nbr_jk->rel_box ); + rvec_Scale( force, +CEhb2, dcos_theta_dk ); + rvec_Add( system->atoms[k].f, force ); + rvec_iMultiply( ext_press, rel_jk, force ); + rvec_ScaledAdd( data->ext_press, 1.0, ext_press ); + + //dr terms + rvec_ScaledAdd( system->atoms[j].f, -CEhb3 / r_jk, dvec_jk ); + + rvec_Scale( force, CEhb3 / r_jk, dvec_jk ); + rvec_Add( system->atoms[k].f, force ); + rvec_iMultiply( ext_press, rel_jk, force ); + rvec_ScaledAdd( data->ext_press, 1.0, ext_press ); + + /* This part is intended for a fully-flexible box */ + /* rvec_OuterProduct( temp_rtensor, + dcos_theta_di, system->atoms[i].x ); + rtensor_Scale( total_rtensor, -CEhb2, temp_rtensor ); + + rvec_ScaledSum( temp_rvec, -CEhb2, dcos_theta_dj, + -CEhb3/r_jk, pbond_jk->dvec ); + rvec_OuterProduct( temp_rtensor, + temp_rvec, system->atoms[j].x ); + rtensor_Add( total_rtensor, temp_rtensor ); + + rvec_ScaledSum( temp_rvec, -CEhb2, dcos_theta_dk, + +CEhb3/r_jk, pbond_jk->dvec ); + rvec_OuterProduct( temp_rtensor, + temp_rvec, system->atoms[k].x ); + rtensor_Add( total_rtensor, temp_rtensor ); + + if( pbond_ij->imaginary || pbond_jk->imaginary ) + rtensor_ScaledAdd( data->flex_bar.P, -1.0, total_rtensor ); + else + rtensor_Add( data->flex_bar.P, total_rtensor ); */ + } + #ifdef TEST_ENERGY - /*fprintf( out_control->ehb, - "%23.15e%23.15e%23.15e\n%23.15e%23.15e%23.15e\n%23.15e%23.15e%23.15e\n", - dcos_theta_di[0], dcos_theta_di[1], dcos_theta_di[2], - dcos_theta_dj[0], dcos_theta_dj[1], dcos_theta_dj[2], - dcos_theta_dk[0], dcos_theta_dk[1], dcos_theta_dk[2]); - fprintf( out_control->ehb, "%23.15e%23.15e%23.15e\n", - CEhb1, CEhb2, CEhb3 ); */ - fprintf( stderr, //out_control->ehb, - "%6d%6d%6d%23.15e%23.15e%23.15e%23.15e%23.15e\n", - workspace->orig_id[i], - workspace->orig_id[j], - workspace->orig_id[k], - r_jk, theta, bo_ij->BO, e_hb, data->E_HB ); - + /*fprintf( out_control->ehb, + "%23.15e%23.15e%23.15e\n%23.15e%23.15e%23.15e\n%23.15e%23.15e%23.15e\n", + dcos_theta_di[0], dcos_theta_di[1], dcos_theta_di[2], + dcos_theta_dj[0], dcos_theta_dj[1], dcos_theta_dj[2], + dcos_theta_dk[0], dcos_theta_dk[1], dcos_theta_dk[2]); + fprintf( out_control->ehb, "%23.15e%23.15e%23.15e\n", + CEhb1, CEhb2, CEhb3 ); */ + fprintf( stderr, //out_control->ehb, + "%6d%6d%6d%23.15e%23.15e%23.15e%23.15e%23.15e\n", + workspace->orig_id[i], + workspace->orig_id[j], + workspace->orig_id[k], + r_jk, theta, bo_ij->BO, e_hb, data->E_HB ); + #endif #ifdef TEST_FORCES - // dbo term - Add_dBO( system, lists, j, pi, +CEhb1, workspace->f_hb ); - // dcos terms - rvec_ScaledAdd( workspace->f_hb[i], +CEhb2, dcos_theta_di ); - rvec_ScaledAdd( workspace->f_hb[j], +CEhb2, dcos_theta_dj ); - rvec_ScaledAdd( workspace->f_hb[k], +CEhb2, dcos_theta_dk ); - // dr terms - rvec_ScaledAdd( workspace->f_hb[j], -CEhb3/r_jk, dvec_jk ); - rvec_ScaledAdd( workspace->f_hb[k], +CEhb3/r_jk, dvec_jk ); + // dbo term + Add_dBO( system, lists, j, pi, +CEhb1, workspace->f_hb ); + // dcos terms + rvec_ScaledAdd( workspace->f_hb[i], +CEhb2, dcos_theta_di ); + rvec_ScaledAdd( workspace->f_hb[j], +CEhb2, dcos_theta_dj ); + rvec_ScaledAdd( workspace->f_hb[k], +CEhb2, dcos_theta_dk ); + // dr terms + rvec_ScaledAdd( workspace->f_hb[j], -CEhb3 / r_jk, dvec_jk ); + rvec_ScaledAdd( workspace->f_hb[k], +CEhb3 / r_jk, dvec_jk ); #endif - } - } - } - } - - /* fprintf( stderr, "hydbonds: ext_press (%23.15e %23.15e %23.15e)\n", - data->ext_press[0], data->ext_press[1], data->ext_press[2] ); */ - + } + } + } + } + + /* fprintf( stderr, "hydbonds: ext_press (%23.15e %23.15e %23.15e)\n", + data->ext_press[0], data->ext_press[1], data->ext_press[2] ); */ + #ifdef TEST_FORCES - fprintf( stderr, "Number of hydrogen bonds: %d\n", num_hb_intrs ); - fprintf( stderr, "Hydrogen Bond Energy: %g\n", data->E_HB ); + fprintf( stderr, "Number of hydrogen bonds: %d\n", num_hb_intrs ); + fprintf( stderr, "Hydrogen Bond Energy: %g\n", data->E_HB ); #endif } diff --git a/puremd_rc_1003/sPuReMD/three_body_interactions.h b/puremd_rc_1003/sPuReMD/three_body_interactions.h index 7a1d67e3..55a1188b 100644 --- a/puremd_rc_1003/sPuReMD/three_body_interactions.h +++ b/puremd_rc_1003/sPuReMD/three_body_interactions.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -25,13 +25,13 @@ #include "mytypes.h" void Three_Body_Interactions( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); + static_storage*, list**, output_controls* ); void Hydrogen_Bonds( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); + static_storage*, list**, output_controls* ); void Calculate_Theta( rvec, real, rvec, real, real*, real* ); - + void Calculate_dCos_Theta( rvec, real, rvec, real, rvec*, rvec*, rvec* ); - + #endif diff --git a/puremd_rc_1003/sPuReMD/traj.c b/puremd_rc_1003/sPuReMD/traj.c index bbff8f15..49a1595a 100644 --- a/puremd_rc_1003/sPuReMD/traj.c +++ b/puremd_rc_1003/sPuReMD/traj.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -26,426 +26,438 @@ /* CUSTOM FORMAT ROUTINES */ /************************************************/ -int Write_Custom_Header(reax_system *system, control_params *control, - static_storage *workspace, output_controls *out_control) +int Write_Custom_Header(reax_system *system, control_params *control, + static_storage *workspace, output_controls *out_control) { - int i, header_len, control_block_len, frame_format_len; - // char buffer[2048]; - char control_block[2048]; - char frame_format[2048]; - char atom_format[100], bond_format[100], angle_format[100]; - - sprintf( control_block, CONTROL_BLOCK, - system->N, - control->restart, - control->restart_from, - control->random_vel, - out_control->restart_freq, - control->ensemble, - control->nsteps, - control->dt, - control->reposition_atoms, - control->restrict_bonds, - control->tabulate, - control->nbr_cut, - control->r_cut, - control->bg_cut, - control->bo_cut, - control->thb_cut, - control->hb_cut, - control->q_err, - control->T_init, - control->T_final, - control->Tau_T, - control->T_mode, - control->T_rate, - control->T_freq, - control->P[0], control->P[1], control->P[2], - control->Tau_P[0], control->Tau_P[1], control->Tau_P[2], - control->compressibility, - control->press_mode, - control->remove_CoM_vel, - out_control->write_steps, - out_control->traj_compress, - out_control->traj_format, - out_control->atom_format, - out_control->bond_info, - out_control->angle_info, - out_control->energy_update_freq, - control->molec_anal, - control->freq_molec_anal ); - - control_block_len = strlen( control_block ); - - - sprintf( frame_format, "Frame Format: %d\n%s\n%s\n", - NUM_FRAME_GLOBALS, FRAME_GLOBALS_FORMAT, FRAME_GLOBAL_NAMES ); - - atom_format[0] = OPT_NOATOM; - switch( out_control->atom_format ) + int i, header_len, control_block_len, frame_format_len; + // char buffer[2048]; + char control_block[2048]; + char frame_format[2048]; + char atom_format[100], bond_format[100], angle_format[100]; + + sprintf( control_block, CONTROL_BLOCK, + system->N, + control->restart, + control->restart_from, + control->random_vel, + out_control->restart_freq, + control->ensemble, + control->nsteps, + control->dt, + control->reposition_atoms, + control->restrict_bonds, + control->tabulate, + control->nbr_cut, + control->r_cut, + control->bg_cut, + control->bo_cut, + control->thb_cut, + control->hb_cut, + control->q_err, + control->T_init, + control->T_final, + control->Tau_T, + control->T_mode, + control->T_rate, + control->T_freq, + control->P[0], control->P[1], control->P[2], + control->Tau_P[0], control->Tau_P[1], control->Tau_P[2], + control->compressibility, + control->press_mode, + control->remove_CoM_vel, + out_control->write_steps, + out_control->traj_compress, + out_control->traj_format, + out_control->atom_format, + out_control->bond_info, + out_control->angle_info, + out_control->energy_update_freq, + control->molec_anal, + control->freq_molec_anal ); + + control_block_len = strlen( control_block ); + + + sprintf( frame_format, "Frame Format: %d\n%s\n%s\n", + NUM_FRAME_GLOBALS, FRAME_GLOBALS_FORMAT, FRAME_GLOBAL_NAMES ); + + atom_format[0] = OPT_NOATOM; + switch ( out_control->atom_format ) { - case OPT_ATOM_BASIC: sprintf( atom_format, "Atom_Basic: %s", ATOM_BASIC ); - break; - case OPT_ATOM_wF: sprintf( atom_format, "Atom_wF: %s", ATOM_wF ); - break; - case OPT_ATOM_wV: sprintf( atom_format, "Atom_wV: %s", ATOM_wV ); - break; - case OPT_ATOM_FULL: sprintf( atom_format, "Atom_Full: %s", ATOM_FULL ); - break; - } - strcat( frame_format, atom_format ); - - bond_format[0] = OPT_NOBOND; - if( out_control->bond_info == OPT_BOND_BASIC ) - sprintf( bond_format, "Bond_Line: %s", BOND_BASIC ); - else if( out_control->bond_info == OPT_BOND_FULL ) - sprintf( bond_format, "Bond_Line_Full: %s", BOND_FULL ); - strcat( frame_format, bond_format ); - - angle_format[0] = OPT_NOANGLE; - if( out_control->angle_info == OPT_ANGLE_BASIC ) - sprintf( angle_format, "Angle_Line: %s", ANGLE_BASIC ); - strcat( frame_format, angle_format ); - - frame_format_len = strlen( frame_format ); - - - header_len = HEADER_INIT_LEN + (control_block_len + SIZE_INFO_LEN2)+ - (frame_format_len + SIZE_INFO_LEN2) + - (ATOM_MAPPING_LEN * system->N + SIZE_INFO_LEN2); - - out_control->write( out_control->trj, HEADER_INIT, - header_len, HEADER_INIT_LEN, out_control->traj_title ); - - out_control->write( out_control->trj, SIZE_INFO_LINE2, - control_block_len + (frame_format_len + SIZE_INFO_LEN2) + - (ATOM_MAPPING_LEN * system->N + SIZE_INFO_LEN2), - control_block_len ); - out_control->write( out_control->trj, "%s", control_block ); - - out_control->write( out_control->trj, SIZE_INFO_LINE2, - frame_format_len + - (ATOM_MAPPING_LEN * system->N + SIZE_INFO_LEN2), - frame_format_len ); - out_control->write( out_control->trj, "%s", frame_format ); - - out_control->write( out_control->trj, SIZE_INFO_LINE2, - ATOM_MAPPING_LEN * system->N, - ATOM_MAPPING_LEN * system->N ); - - for( i = 0; i < system->N; ++i ) - out_control->write( out_control->trj, ATOM_MAPPING, - workspace->orig_id[i], - system->atoms[i].type, - system->atoms[i].name, - system->reaxprm.sbp[ system->atoms[i].type ].mass ); - - fflush( out_control->trj ); - - return 0; + case OPT_ATOM_BASIC: + sprintf( atom_format, "Atom_Basic: %s", ATOM_BASIC ); + break; + case OPT_ATOM_wF: + sprintf( atom_format, "Atom_wF: %s", ATOM_wF ); + break; + case OPT_ATOM_wV: + sprintf( atom_format, "Atom_wV: %s", ATOM_wV ); + break; + case OPT_ATOM_FULL: + sprintf( atom_format, "Atom_Full: %s", ATOM_FULL ); + break; + } + strcat( frame_format, atom_format ); + + bond_format[0] = OPT_NOBOND; + if ( out_control->bond_info == OPT_BOND_BASIC ) + sprintf( bond_format, "Bond_Line: %s", BOND_BASIC ); + else if ( out_control->bond_info == OPT_BOND_FULL ) + sprintf( bond_format, "Bond_Line_Full: %s", BOND_FULL ); + strcat( frame_format, bond_format ); + + angle_format[0] = OPT_NOANGLE; + if ( out_control->angle_info == OPT_ANGLE_BASIC ) + sprintf( angle_format, "Angle_Line: %s", ANGLE_BASIC ); + strcat( frame_format, angle_format ); + + frame_format_len = strlen( frame_format ); + + + header_len = HEADER_INIT_LEN + (control_block_len + SIZE_INFO_LEN2) + + (frame_format_len + SIZE_INFO_LEN2) + + (ATOM_MAPPING_LEN * system->N + SIZE_INFO_LEN2); + + out_control->write( out_control->trj, HEADER_INIT, + header_len, HEADER_INIT_LEN, out_control->traj_title ); + + out_control->write( out_control->trj, SIZE_INFO_LINE2, + control_block_len + (frame_format_len + SIZE_INFO_LEN2) + + (ATOM_MAPPING_LEN * system->N + SIZE_INFO_LEN2), + control_block_len ); + out_control->write( out_control->trj, "%s", control_block ); + + out_control->write( out_control->trj, SIZE_INFO_LINE2, + frame_format_len + + (ATOM_MAPPING_LEN * system->N + SIZE_INFO_LEN2), + frame_format_len ); + out_control->write( out_control->trj, "%s", frame_format ); + + out_control->write( out_control->trj, SIZE_INFO_LINE2, + ATOM_MAPPING_LEN * system->N, + ATOM_MAPPING_LEN * system->N ); + + for ( i = 0; i < system->N; ++i ) + out_control->write( out_control->trj, ATOM_MAPPING, + workspace->orig_id[i], + system->atoms[i].type, + system->atoms[i].name, + system->reaxprm.sbp[ system->atoms[i].type ].mass ); + + fflush( out_control->trj ); + + return 0; } -int Append_Custom_Frame( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +int Append_Custom_Frame( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i, j, pi, pk, pk_j; - int write_atoms, write_bonds, write_angles; - int frame_len, atom_line_len, bond_line_len, angle_line_len, rest_of_frame_len; - int frame_globals_len, num_bonds, num_thb_intrs; - real P; - char buffer[2048]; - list *bonds = (*lists) + BONDS; - list *thb_intrs = (*lists) + THREE_BODIES; - bond_data *bo_ij; - - - /* IMPORTANT: This whole part will go to init_trj after finalized! */ - switch( out_control->atom_format ) + int i, j, pi, pk, pk_j; + int write_atoms, write_bonds, write_angles; + int frame_len, atom_line_len, bond_line_len, angle_line_len, rest_of_frame_len; + int frame_globals_len, num_bonds, num_thb_intrs; + real P; + char buffer[2048]; + list *bonds = (*lists) + BONDS; + list *thb_intrs = (*lists) + THREE_BODIES; + bond_data *bo_ij; + + + /* IMPORTANT: This whole part will go to init_trj after finalized! */ + switch ( out_control->atom_format ) { - case OPT_ATOM_BASIC: - atom_line_len = ATOM_BASIC_LEN; - write_atoms = 1; - break; - case OPT_ATOM_wF: - atom_line_len = ATOM_wF_LEN; - write_atoms = 1; - break; - case OPT_ATOM_wV: - atom_line_len = ATOM_wV_LEN; - write_atoms = 1; - break; - case OPT_ATOM_FULL: - atom_line_len = ATOM_FULL_LEN; - write_atoms = 1; - break; - default: - atom_line_len = 0; - write_atoms = 0; - } - - - /* bond preparations */ - bond_line_len = write_bonds = 0; - if( out_control->bond_info == OPT_BOND_BASIC ) + case OPT_ATOM_BASIC: + atom_line_len = ATOM_BASIC_LEN; + write_atoms = 1; + break; + case OPT_ATOM_wF: + atom_line_len = ATOM_wF_LEN; + write_atoms = 1; + break; + case OPT_ATOM_wV: + atom_line_len = ATOM_wV_LEN; + write_atoms = 1; + break; + case OPT_ATOM_FULL: + atom_line_len = ATOM_FULL_LEN; + write_atoms = 1; + break; + default: + atom_line_len = 0; + write_atoms = 0; + } + + + /* bond preparations */ + bond_line_len = write_bonds = 0; + if ( out_control->bond_info == OPT_BOND_BASIC ) { - bond_line_len = BOND_BASIC_LEN; - write_bonds = 1; + bond_line_len = BOND_BASIC_LEN; + write_bonds = 1; } - else if( out_control->bond_info == OPT_BOND_FULL ) + else if ( out_control->bond_info == OPT_BOND_FULL ) { - bond_line_len = BOND_FULL_LEN; - write_bonds = 1; + bond_line_len = BOND_FULL_LEN; + write_bonds = 1; } - num_bonds = 0; - if( write_bonds ) + num_bonds = 0; + if ( write_bonds ) { - for( i = 0; i < system->N; ++i ) - for( j = Start_Index( i, bonds ); j < End_Index( i, bonds ); ++j ) - if( i < bonds->select.bond_list[j].nbr && - bonds->select.bond_list[j].bo_data.BO >= control->bg_cut ) - ++num_bonds; + for ( i = 0; i < system->N; ++i ) + for ( j = Start_Index( i, bonds ); j < End_Index( i, bonds ); ++j ) + if ( i < bonds->select.bond_list[j].nbr && + bonds->select.bond_list[j].bo_data.BO >= control->bg_cut ) + ++num_bonds; } - /* angle preparations */ - if( out_control->angle_info == OPT_ANGLE_BASIC ) + /* angle preparations */ + if ( out_control->angle_info == OPT_ANGLE_BASIC ) { - angle_line_len = ANGLE_BASIC_LEN; - write_angles = 1; + angle_line_len = ANGLE_BASIC_LEN; + write_angles = 1; } - else + else { - angle_line_len = 0; - write_angles = 0; + angle_line_len = 0; + write_angles = 0; } - num_thb_intrs = 0; - if( write_angles ) { - for( j = 0; j < system->N; ++j ) - for( pi = Start_Index(j, bonds); pi < End_Index(j, bonds); ++pi ) - if( bonds->select.bond_list[pi].bo_data.BO >= control->bg_cut ) - // physical j&i bond - for( pk = Start_Index( pi, thb_intrs ); - pk < End_Index( pi, thb_intrs ); ++pk ) - if( bonds->select.bond_list[pi].nbr < - thb_intrs->select.three_body_list[pk].thb ) { - // get k's pointer on j's bond list - pk_j = thb_intrs->select.three_body_list[pk].pthb; - - if( bonds->select.bond_list[pk_j].bo_data.BO >= control->bg_cut ) - // physical j&k bond - ++num_thb_intrs; - } - } - - - - /* get correct pressure */ - if( control->ensemble == NPT || control->ensemble == sNPT ) - P = data->flex_bar.P_scalar; - else if( control->ensemble == iNPT ) - P = data->iso_bar.P; - else P = 0; - - - /* calculate total frame length*/ - sprintf( buffer, FRAME_GLOBALS, - data->step, data->time, - data->E_Tot, data->E_Pot, E_CONV * data->E_Kin, data->therm.T, - P, system->box.volume, - system->box.box_norms[0], - system->box.box_norms[1], - system->box.box_norms[2], - 90.0, 90.0, 90.0, // IMPORTANT: need to rewrite for flexible boxes! - data->E_BE, - data->E_Ov, data->E_Un, data->E_Lp, - data->E_Ang, data->E_Pen, data->E_Coa, data->E_HB, - data->E_Tor, data->E_Con, - data->E_vdW, data->E_Ele, data->E_Pol ); - frame_globals_len = strlen( buffer ); - - frame_len = frame_globals_len + - write_atoms * SIZE_INFO_LEN3 + system->N * atom_line_len + - write_bonds * SIZE_INFO_LEN3 + num_bonds * bond_line_len + - write_angles * SIZE_INFO_LEN3 + num_thb_intrs * angle_line_len; - - - /* write size info & frame globals */ - out_control->write( out_control->trj, SIZE_INFO_LINE2, - frame_len, frame_globals_len ); - out_control->write( out_control->trj, "%s", buffer ); - - - /* write size info & atom lines */ - if( write_atoms ) + num_thb_intrs = 0; + if ( write_angles ) { - rest_of_frame_len = system->N * atom_line_len + - write_bonds * SIZE_INFO_LEN3 + num_bonds * bond_line_len + - write_angles * SIZE_INFO_LEN3 + num_thb_intrs * angle_line_len; - - out_control->write( out_control->trj, SIZE_INFO_LINE3, - rest_of_frame_len, system->N * atom_line_len, - system->N ); + for ( j = 0; j < system->N; ++j ) + for ( pi = Start_Index(j, bonds); pi < End_Index(j, bonds); ++pi ) + if ( bonds->select.bond_list[pi].bo_data.BO >= control->bg_cut ) + // physical j&i bond + for ( pk = Start_Index( pi, thb_intrs ); + pk < End_Index( pi, thb_intrs ); ++pk ) + if ( bonds->select.bond_list[pi].nbr < + thb_intrs->select.three_body_list[pk].thb ) + { + // get k's pointer on j's bond list + pk_j = thb_intrs->select.three_body_list[pk].pthb; + + if ( bonds->select.bond_list[pk_j].bo_data.BO >= control->bg_cut ) + // physical j&k bond + ++num_thb_intrs; + } } - switch( out_control->atom_format ) + + + /* get correct pressure */ + if ( control->ensemble == NPT || control->ensemble == sNPT ) + P = data->flex_bar.P_scalar; + else if ( control->ensemble == iNPT ) + P = data->iso_bar.P; + else P = 0; + + + /* calculate total frame length*/ + sprintf( buffer, FRAME_GLOBALS, + data->step, data->time, + data->E_Tot, data->E_Pot, E_CONV * data->E_Kin, data->therm.T, + P, system->box.volume, + system->box.box_norms[0], + system->box.box_norms[1], + system->box.box_norms[2], + 90.0, 90.0, 90.0, // IMPORTANT: need to rewrite for flexible boxes! + data->E_BE, + data->E_Ov, data->E_Un, data->E_Lp, + data->E_Ang, data->E_Pen, data->E_Coa, data->E_HB, + data->E_Tor, data->E_Con, + data->E_vdW, data->E_Ele, data->E_Pol ); + frame_globals_len = strlen( buffer ); + + frame_len = frame_globals_len + + write_atoms * SIZE_INFO_LEN3 + system->N * atom_line_len + + write_bonds * SIZE_INFO_LEN3 + num_bonds * bond_line_len + + write_angles * SIZE_INFO_LEN3 + num_thb_intrs * angle_line_len; + + + /* write size info & frame globals */ + out_control->write( out_control->trj, SIZE_INFO_LINE2, + frame_len, frame_globals_len ); + out_control->write( out_control->trj, "%s", buffer ); + + + /* write size info & atom lines */ + if ( write_atoms ) { - case 4: - for( i = 0; i < system->N; ++i ) - out_control->write( out_control->trj, ATOM_BASIC, - workspace->orig_id[i], - system->atoms[i].x[0], - system->atoms[i].x[1], - system->atoms[i].x[2], - system->atoms[i].q ); - break; + rest_of_frame_len = system->N * atom_line_len + + write_bonds * SIZE_INFO_LEN3 + num_bonds * bond_line_len + + write_angles * SIZE_INFO_LEN3 + num_thb_intrs * angle_line_len; + + out_control->write( out_control->trj, SIZE_INFO_LINE3, + rest_of_frame_len, system->N * atom_line_len, + system->N ); + } + + switch ( out_control->atom_format ) + { + case 4: + for ( i = 0; i < system->N; ++i ) + out_control->write( out_control->trj, ATOM_BASIC, + workspace->orig_id[i], + system->atoms[i].x[0], + system->atoms[i].x[1], + system->atoms[i].x[2], + system->atoms[i].q ); + break; case 5: - for( i = 0; i < system->N; ++i ) - out_control->write( out_control->trj, ATOM_wF, - workspace->orig_id[i], - system->atoms[i].x[0], - system->atoms[i].x[1], - system->atoms[i].x[2], - system->atoms[i].f[0], - system->atoms[i].f[1], - system->atoms[i].f[2], - system->atoms[i].q ); - break; - case 6: - for( i = 0; i < system->N; ++i ) - out_control->write( out_control->trj, ATOM_wV, - workspace->orig_id[i], - system->atoms[i].x[0], - system->atoms[i].x[1], - system->atoms[i].x[2], - system->atoms[i].v[0], - system->atoms[i].v[1], - system->atoms[i].v[2], - system->atoms[i].q ); - break; - case 7: - for( i = 0; i < system->N; ++i ) - out_control->write( out_control->trj, ATOM_FULL, - workspace->orig_id[i], - system->atoms[i].x[0], - system->atoms[i].x[1], - system->atoms[i].x[2], - system->atoms[i].v[0], - system->atoms[i].v[1], - system->atoms[i].v[2], - system->atoms[i].f[0], - system->atoms[i].f[1], - system->atoms[i].f[2], - system->atoms[i].q ); - break; - } - fflush( out_control->trj ); - - - /* write size info & bond lines */ - if( write_bonds ) + for ( i = 0; i < system->N; ++i ) + out_control->write( out_control->trj, ATOM_wF, + workspace->orig_id[i], + system->atoms[i].x[0], + system->atoms[i].x[1], + system->atoms[i].x[2], + system->atoms[i].f[0], + system->atoms[i].f[1], + system->atoms[i].f[2], + system->atoms[i].q ); + break; + case 6: + for ( i = 0; i < system->N; ++i ) + out_control->write( out_control->trj, ATOM_wV, + workspace->orig_id[i], + system->atoms[i].x[0], + system->atoms[i].x[1], + system->atoms[i].x[2], + system->atoms[i].v[0], + system->atoms[i].v[1], + system->atoms[i].v[2], + system->atoms[i].q ); + break; + case 7: + for ( i = 0; i < system->N; ++i ) + out_control->write( out_control->trj, ATOM_FULL, + workspace->orig_id[i], + system->atoms[i].x[0], + system->atoms[i].x[1], + system->atoms[i].x[2], + system->atoms[i].v[0], + system->atoms[i].v[1], + system->atoms[i].v[2], + system->atoms[i].f[0], + system->atoms[i].f[1], + system->atoms[i].f[2], + system->atoms[i].q ); + break; + } + fflush( out_control->trj ); + + + /* write size info & bond lines */ + if ( write_bonds ) { - rest_of_frame_len = num_bonds * bond_line_len + - write_angles * SIZE_INFO_LEN3 + num_thb_intrs * angle_line_len; + rest_of_frame_len = num_bonds * bond_line_len + + write_angles * SIZE_INFO_LEN3 + num_thb_intrs * angle_line_len; + + out_control->write( out_control->trj, SIZE_INFO_LINE3, + rest_of_frame_len, num_bonds * bond_line_len, + num_bonds ); + } + + if ( out_control->bond_info == 1 ) + { + for ( i = 0; i < system->N; ++i ) + for ( j = Start_Index( i, bonds ); j < End_Index( i, bonds ); ++j ) + if ( i < bonds->select.bond_list[j].nbr && + bonds->select.bond_list[j].bo_data.BO >= control->bg_cut ) + { + bo_ij = &( bonds->select.bond_list[j] ); + out_control->write( out_control->trj, BOND_BASIC, + workspace->orig_id[i], + workspace->orig_id[bo_ij->nbr], + bo_ij->d, bo_ij->bo_data.BO ); + } + } + else if ( out_control->bond_info == 2 ) + { + for ( i = 0; i < system->N; ++i ) + for ( j = Start_Index( i, bonds ); j < End_Index( i, bonds ); ++j ) + if ( i < bonds->select.bond_list[j].nbr && + bonds->select.bond_list[j].bo_data.BO >= control->bg_cut ) + { + bo_ij = &( bonds->select.bond_list[j] ); + out_control->write( out_control->trj, BOND_FULL, + workspace->orig_id[i], + workspace->orig_id[bo_ij->nbr], + bo_ij->d, bo_ij->bo_data.BO, bo_ij->bo_data.BO_s, + bo_ij->bo_data.BO_pi, bo_ij->bo_data.BO_pi2 ); + } + } - out_control->write( out_control->trj, SIZE_INFO_LINE3, - rest_of_frame_len, num_bonds * bond_line_len, - num_bonds ); + fflush( out_control->trj ); + + + /* write size info & angle lines */ + if ( out_control->angle_info ) + { + out_control->write( out_control->trj, SIZE_INFO_LINE3, + num_thb_intrs * angle_line_len, + num_thb_intrs * angle_line_len, num_thb_intrs ); + + for ( j = 0; j < system->N; ++j ) + for ( pi = Start_Index(j, bonds); pi < End_Index(j, bonds); ++pi ) + if ( bonds->select.bond_list[pi].bo_data.BO >= control->bg_cut ) + // physical j&i bond + for ( pk = Start_Index( pi, thb_intrs ); + pk < End_Index( pi, thb_intrs ); ++pk ) + if ( bonds->select.bond_list[pi].nbr < + thb_intrs->select.three_body_list[pk].thb ) + { + pk_j = thb_intrs->select.three_body_list[pk].pthb; + // get k's pointer on j's bond list + + if ( bonds->select.bond_list[pk_j].bo_data.BO >= control->bg_cut ) + // physical j&k bond + out_control->write( out_control->trj, ANGLE_BASIC, + workspace->orig_id[bonds->select.bond_list[pi].nbr], + workspace->orig_id[j], + workspace->orig_id[thb_intrs->select.three_body_list[pk].thb], + RAD2DEG(thb_intrs->select.three_body_list[pk].theta) ); + } } - if( out_control->bond_info == 1 ) { - for( i = 0; i < system->N; ++i ) - for( j = Start_Index( i, bonds ); j < End_Index( i, bonds ); ++j ) - if( i < bonds->select.bond_list[j].nbr && - bonds->select.bond_list[j].bo_data.BO >= control->bg_cut ) { - bo_ij = &( bonds->select.bond_list[j] ); - out_control->write( out_control->trj, BOND_BASIC, - workspace->orig_id[i], - workspace->orig_id[bo_ij->nbr], - bo_ij->d, bo_ij->bo_data.BO ); - } - } - else if( out_control->bond_info == 2 ) { - for( i = 0; i < system->N; ++i ) - for( j = Start_Index( i, bonds ); j < End_Index( i, bonds ); ++j ) - if( i < bonds->select.bond_list[j].nbr && - bonds->select.bond_list[j].bo_data.BO >= control->bg_cut ) { - bo_ij = &( bonds->select.bond_list[j] ); - out_control->write( out_control->trj, BOND_FULL, - workspace->orig_id[i], - workspace->orig_id[bo_ij->nbr], - bo_ij->d, bo_ij->bo_data.BO, bo_ij->bo_data.BO_s, - bo_ij->bo_data.BO_pi, bo_ij->bo_data.BO_pi2 ); - } - } - - fflush( out_control->trj ); - - - /* write size info & angle lines */ - if( out_control->angle_info ) { - out_control->write( out_control->trj, SIZE_INFO_LINE3, - num_thb_intrs * angle_line_len, - num_thb_intrs * angle_line_len, num_thb_intrs ); - - for( j = 0; j < system->N; ++j ) - for( pi = Start_Index(j, bonds); pi < End_Index(j, bonds); ++pi ) - if( bonds->select.bond_list[pi].bo_data.BO >= control->bg_cut ) - // physical j&i bond - for( pk = Start_Index( pi, thb_intrs ); - pk < End_Index( pi, thb_intrs ); ++pk ) - if( bonds->select.bond_list[pi].nbr < - thb_intrs->select.three_body_list[pk].thb ) { - pk_j = thb_intrs->select.three_body_list[pk].pthb; - // get k's pointer on j's bond list - - if( bonds->select.bond_list[pk_j].bo_data.BO >= control->bg_cut ) - // physical j&k bond - out_control->write( out_control->trj, ANGLE_BASIC, - workspace->orig_id[bonds->select.bond_list[pi].nbr], - workspace->orig_id[j], - workspace->orig_id[thb_intrs->select.three_body_list[pk].thb], - RAD2DEG(thb_intrs->select.three_body_list[pk].theta) ); - } - } - - fflush( out_control->trj ); - - return 0; + fflush( out_control->trj ); + + return 0; } void Read_Traj( output_controls *out_control, char *traj_name ) { - int skip_all, skip_part, n; - char size_buffer[50]; - // char read_buffer[2048]; - - out_control->trj = gzopen( traj_name, "r" ); - - fprintf( stderr, "file opened!\n" ); - - while( !gzeof( out_control->trj ) ) - { - if( gzgets( out_control->trj, size_buffer, 50 ) == Z_NULL ) - break; - - fprintf( stderr, "read line\n" ); - - if( strlen( size_buffer ) >= SIZE_INFO_LEN3 ) - sscanf( size_buffer, "%d %d %d", &skip_all, &skip_part, &n ); - else - sscanf( size_buffer, "%d %d", &skip_all, &skip_part ); + int skip_all, skip_part, n; + char size_buffer[50]; + // char read_buffer[2048]; + + out_control->trj = gzopen( traj_name, "r" ); + + fprintf( stderr, "file opened!\n" ); - fprintf( stderr, "%d %d\n", skip_all, skip_part ); + while ( !gzeof( out_control->trj ) ) + { + if ( gzgets( out_control->trj, size_buffer, 50 ) == Z_NULL ) + break; + + fprintf( stderr, "read line\n" ); - gzseek( out_control->trj, skip_part, SEEK_CUR ); - } + if ( strlen( size_buffer ) >= SIZE_INFO_LEN3 ) + sscanf( size_buffer, "%d %d %d", &skip_all, &skip_part, &n ); + else + sscanf( size_buffer, "%d %d", &skip_all, &skip_part ); - gzclose( out_control->trj ); + fprintf( stderr, "%d %d\n", skip_all, skip_part ); + + gzseek( out_control->trj, skip_part, SEEK_CUR ); + } + + gzclose( out_control->trj ); } @@ -455,36 +467,36 @@ void Read_Traj( output_controls *out_control, char *traj_name ) /************ XYZ FORMAT ROUTINES ***************/ /********************************************************/ -int Write_xyz_Header( reax_system *system, control_params *control, - static_storage* workspace, output_controls *out_control ) +int Write_xyz_Header( reax_system *system, control_params *control, + static_storage* workspace, output_controls *out_control ) { - fflush( out_control->trj ); - - return 1; + fflush( out_control->trj ); + + return 1; } -int Append_xyz_Frame( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +int Append_xyz_Frame( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i; + int i; + + out_control->write( out_control->trj, "%d\n", system->N ); - out_control->write( out_control->trj, "%d\n", system->N ); + out_control->write( out_control->trj, "%d\t%8.3f\t%8.3f\t%8.3f\t%8.3f\n", + data->step, + data->E_Tot, data->E_Pot, + E_CONV * data->E_Kin, data->therm.T ); - out_control->write( out_control->trj, "%d\t%8.3f\t%8.3f\t%8.3f\t%8.3f\n", - data->step, - data->E_Tot, data->E_Pot, - E_CONV*data->E_Kin, data->therm.T ); - - for( i = 0; i < system->N; ++i ) - out_control->write( out_control->trj, "%3s %10.5f %10.5f %10.5f\n", - system->reaxprm.sbp[ system->atoms[i].type ].name, - system->atoms[i].x[0], - system->atoms[i].x[1], - system->atoms[i].x[2] ); + for ( i = 0; i < system->N; ++i ) + out_control->write( out_control->trj, "%3s %10.5f %10.5f %10.5f\n", + system->reaxprm.sbp[ system->atoms[i].type ].name, + system->atoms[i].x[0], + system->atoms[i].x[1], + system->atoms[i].x[2] ); - fflush( out_control->trj ); + fflush( out_control->trj ); - return 1; + return 1; } diff --git a/puremd_rc_1003/sPuReMD/traj.h b/puremd_rc_1003/sPuReMD/traj.h index 092f7100..0e759059 100644 --- a/puremd_rc_1003/sPuReMD/traj.h +++ b/puremd_rc_1003/sPuReMD/traj.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -74,17 +74,18 @@ #define SIZE_INFO_LINE3 "%-10d %-10d %-10d\n" #define SIZE_INFO_LEN3 33 -enum ATOM_LINE_OPTS {OPT_NOATOM = 0, OPT_ATOM_BASIC = 4, OPT_ATOM_wF = 5, - OPT_ATOM_wV = 6, OPT_ATOM_FULL = 7}; +enum ATOM_LINE_OPTS {OPT_NOATOM = 0, OPT_ATOM_BASIC = 4, OPT_ATOM_wF = 5, + OPT_ATOM_wV = 6, OPT_ATOM_FULL = 7 + }; enum BOND_LINE_OPTS {OPT_NOBOND, OPT_BOND_BASIC, OPT_BOND_FULL}; enum ANGLE_LINE_OPTS {OPT_NOANGLE, OPT_ANGLE_BASIC}; typedef struct { - int no_of_sub_blocks; - int size; - char* buffer; - struct block** sub_blocks; + int no_of_sub_blocks; + int size; + char* buffer; + struct block** sub_blocks; } block; @@ -98,19 +99,19 @@ int Skip_Next_Block( gzFile, int*); {HEADER} size flag char (1) - size of header to skip (int) + size of header to skip (int) Title (char[80]) size flag char (2) size of control param block (int) - Entire control param structure + Entire control param structure size of frame descriptor (int) - Frame descriptor Block + Frame descriptor Block [ Frame descriptor block No. of global quantities lines (say m) (int) - Format for each global quantity line [m]. - Comma separated names for each global quantity line [m]. + Format for each global quantity line [m]. + Comma separated names for each global quantity line [m]. ] - + {FRAMES} size flag char (1) size of the entire frame to skip it (int) @@ -142,17 +143,17 @@ int Skip_Next_Block( gzFile, int*); */ -int Write_Custom_Header( reax_system*, control_params*, - static_storage*, output_controls* ); -int Write_xyz_Header ( reax_system*, control_params*, - static_storage*, output_controls* ); +int Write_Custom_Header( reax_system*, control_params*, + static_storage*, output_controls* ); +int Write_xyz_Header ( reax_system*, control_params*, + static_storage*, output_controls* ); /* Write_Traj_Header( gzfile file, - int No. of lines of global qunatities, - char** format for global quantities, - char** names for global quantities, - control_params* control); + int No. of lines of global qunatities, + char** format for global quantities, + char** names for global quantities, + control_params* control); */ char Write_Traj_Header( FILE*, int, char**, char**, control_params* ); @@ -160,28 +161,28 @@ char Write_Traj_Header( FILE*, int, char**, char**, control_params* ); /* Push_Traj_Frame(gzfile file, reax_system* system, - control_params* control, - simulation_data* data, - static_storage* workspace, - list** lists, - char** various flags); + control_params* control, + simulation_data* data, + static_storage* workspace, + list** lists, + char** various flags); */ -int Push_Traj_Frame( /*gzfile*/ FILE*, reax_system*, control_params*, - simulation_data*, static_storage*, list**, char** ); +int Push_Traj_Frame( /*gzfile*/ FILE*, reax_system*, control_params*, + simulation_data*, static_storage*, list**, char** ); /* Append_Traj_Frame( gzfile file, reax_system* system, control_params* control, - simulation_data* data, - static_storage* workspace, - list** lists, - char** various flags); + simulation_data* data, + static_storage* workspace, + list** lists, + char** various flags); */ -int Append_Custom_Frame( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); -int Append_xyz_Frame ( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); +int Append_Custom_Frame( reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls* ); +int Append_xyz_Frame ( reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls* ); void Read_Traj( output_controls*, char * ); diff --git a/puremd_rc_1003/sPuReMD/two_body_interactions.c b/puremd_rc_1003/sPuReMD/two_body_interactions.c index 9d6acd20..cd005cfe 100644 --- a/puremd_rc_1003/sPuReMD/two_body_interactions.c +++ b/puremd_rc_1003/sPuReMD/two_body_interactions.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -26,526 +26,545 @@ #include "vector.h" -void Bond_Energy( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void Bond_Energy( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i, j, pj; - int start_i, end_i; - int type_i, type_j; - real ebond, pow_BOs_be2, exp_be12, CEbo; - real gp3, gp4, gp7, gp10, gp37; - real exphu, exphua1, exphub1, exphuov, hulpov, estriph; - real decobdbo, decobdboua, decobdboub; - single_body_parameters *sbp_i, *sbp_j; - two_body_parameters *twbp; - bond_order_data *bo_ij; - list *bonds; - - bonds = (*lists) + BONDS; - gp3 = system->reaxprm.gp.l[3]; - gp4 = system->reaxprm.gp.l[4]; - gp7 = system->reaxprm.gp.l[7]; - gp10 = system->reaxprm.gp.l[10]; - gp37 = (int) system->reaxprm.gp.l[37]; - - for( i=0; i < system->N; ++i ) { - start_i = Start_Index(i, bonds); - end_i = End_Index(i, bonds); - //fprintf( stderr, "i=%d start=%d end=%d\n", i, start_i, end_i ); - for( pj = start_i; pj < end_i; ++pj ) - if( i < bonds->select.bond_list[pj].nbr ) { - /* set the pointers */ - j = bonds->select.bond_list[pj].nbr; - type_i = system->atoms[i].type; - type_j = system->atoms[j].type; - sbp_i = &( system->reaxprm.sbp[type_i] ); - sbp_j = &( system->reaxprm.sbp[type_j] ); - twbp = &( system->reaxprm.tbp[type_i][type_j] ); - bo_ij = &( bonds->select.bond_list[pj].bo_data ); - - /* calculate the constants */ - pow_BOs_be2 = POW( bo_ij->BO_s, twbp->p_be2 ); - exp_be12 = EXP( twbp->p_be1 * ( 1.0 - pow_BOs_be2 ) ); - CEbo = -twbp->De_s * exp_be12 * - ( 1.0 - twbp->p_be1 * twbp->p_be2 * pow_BOs_be2 ); - - /* calculate the Bond Energy */ - data->E_BE += ebond = - -twbp->De_s * bo_ij->BO_s * exp_be12 - -twbp->De_p * bo_ij->BO_pi - -twbp->De_pp * bo_ij->BO_pi2; - - /* calculate derivatives of Bond Orders */ - bo_ij->Cdbo += CEbo; - bo_ij->Cdbopi -= (CEbo + twbp->De_p); - bo_ij->Cdbopi2 -= (CEbo + twbp->De_pp); + int i, j, pj; + int start_i, end_i; + int type_i, type_j; + real ebond, pow_BOs_be2, exp_be12, CEbo; + real gp3, gp4, gp7, gp10, gp37; + real exphu, exphua1, exphub1, exphuov, hulpov, estriph; + real decobdbo, decobdboua, decobdboub; + single_body_parameters *sbp_i, *sbp_j; + two_body_parameters *twbp; + bond_order_data *bo_ij; + list *bonds; + + bonds = (*lists) + BONDS; + gp3 = system->reaxprm.gp.l[3]; + gp4 = system->reaxprm.gp.l[4]; + gp7 = system->reaxprm.gp.l[7]; + gp10 = system->reaxprm.gp.l[10]; + gp37 = (int) system->reaxprm.gp.l[37]; + + for ( i = 0; i < system->N; ++i ) + { + start_i = Start_Index(i, bonds); + end_i = End_Index(i, bonds); + //fprintf( stderr, "i=%d start=%d end=%d\n", i, start_i, end_i ); + for ( pj = start_i; pj < end_i; ++pj ) + if ( i < bonds->select.bond_list[pj].nbr ) + { + /* set the pointers */ + j = bonds->select.bond_list[pj].nbr; + type_i = system->atoms[i].type; + type_j = system->atoms[j].type; + sbp_i = &( system->reaxprm.sbp[type_i] ); + sbp_j = &( system->reaxprm.sbp[type_j] ); + twbp = &( system->reaxprm.tbp[type_i][type_j] ); + bo_ij = &( bonds->select.bond_list[pj].bo_data ); + + /* calculate the constants */ + pow_BOs_be2 = POW( bo_ij->BO_s, twbp->p_be2 ); + exp_be12 = EXP( twbp->p_be1 * ( 1.0 - pow_BOs_be2 ) ); + CEbo = -twbp->De_s * exp_be12 * + ( 1.0 - twbp->p_be1 * twbp->p_be2 * pow_BOs_be2 ); + + /* calculate the Bond Energy */ + data->E_BE += ebond = + -twbp->De_s * bo_ij->BO_s * exp_be12 + - twbp->De_p * bo_ij->BO_pi + - twbp->De_pp * bo_ij->BO_pi2; + + /* calculate derivatives of Bond Orders */ + bo_ij->Cdbo += CEbo; + bo_ij->Cdbopi -= (CEbo + twbp->De_p); + bo_ij->Cdbopi2 -= (CEbo + twbp->De_pp); #ifdef TEST_ENERGY - fprintf( out_control->ebond, "%6d%6d%24.15e%24.15e\n", - workspace->orig_id[i], workspace->orig_id[j], - // i+1, j+1, - bo_ij->BO, ebond/*, data->E_BE*/ ); - /* fprintf( out_control->ebond, "%6d%6d%12.6f%12.6f%12.6f\n", - workspace->orig_id[i], workspace->orig_id[j], - CEbo, -twbp->De_p, -twbp->De_pp );*/ + fprintf( out_control->ebond, "%6d%6d%24.15e%24.15e\n", + workspace->orig_id[i], workspace->orig_id[j], + // i+1, j+1, + bo_ij->BO, ebond/*, data->E_BE*/ ); + /* fprintf( out_control->ebond, "%6d%6d%12.6f%12.6f%12.6f\n", + workspace->orig_id[i], workspace->orig_id[j], + CEbo, -twbp->De_p, -twbp->De_pp );*/ #endif #ifdef TEST_FORCES - Add_dBO( system, lists, i, pj, CEbo, workspace->f_be ); - Add_dBOpinpi2( system, lists, i, pj, - -(CEbo + twbp->De_p), -(CEbo + twbp->De_pp), - workspace->f_be, workspace->f_be ); + Add_dBO( system, lists, i, pj, CEbo, workspace->f_be ); + Add_dBOpinpi2( system, lists, i, pj, + -(CEbo + twbp->De_p), -(CEbo + twbp->De_pp), + workspace->f_be, workspace->f_be ); #endif - /* Stabilisation terminal triple bond */ - if( bo_ij->BO >= 1.00 ) { - if( gp37 == 2 || - (sbp_i->mass == 12.0000 && sbp_j->mass == 15.9990) || - (sbp_j->mass == 12.0000 && sbp_i->mass == 15.9990) ) { - // ba = SQR(bo_ij->BO - 2.50); - exphu = EXP( -gp7 * SQR(bo_ij->BO - 2.50) ); - //oboa=abo(j1)-boa; - //obob=abo(j2)-boa; - exphua1 = EXP(-gp3*(workspace->total_bond_order[i]-bo_ij->BO)); - exphub1 = EXP(-gp3*(workspace->total_bond_order[j]-bo_ij->BO)); - //ovoab=abo(j1)-aval(it1)+abo(j2)-aval(it2); - exphuov = EXP(gp4*(workspace->Delta[i] + workspace->Delta[j])); - hulpov = 1.0 / (1.0 + 25.0 * exphuov); - - estriph = gp10 * exphu * hulpov * (exphua1 + exphub1); - //estrain(j1) = estrain(j1) + 0.50*estriph; - //estrain(j2) = estrain(j2) + 0.50*estriph; - data->E_BE += estriph; - - decobdbo = gp10 * exphu * hulpov * (exphua1 + exphub1) * - ( gp3 - 2.0 * gp7 * (bo_ij->BO-2.50) ); - decobdboua = -gp10 * exphu * hulpov * - (gp3*exphua1 + 25.0*gp4*exphuov*hulpov*(exphua1+exphub1)); - decobdboub = -gp10 * exphu * hulpov * - (gp3*exphub1 + 25.0*gp4*exphuov*hulpov*(exphua1+exphub1)); - - bo_ij->Cdbo += decobdbo; - workspace->CdDelta[i] += decobdboua; - workspace->CdDelta[j] += decobdboub; + /* Stabilisation terminal triple bond */ + if ( bo_ij->BO >= 1.00 ) + { + if ( gp37 == 2 || + (sbp_i->mass == 12.0000 && sbp_j->mass == 15.9990) || + (sbp_j->mass == 12.0000 && sbp_i->mass == 15.9990) ) + { + // ba = SQR(bo_ij->BO - 2.50); + exphu = EXP( -gp7 * SQR(bo_ij->BO - 2.50) ); + //oboa=abo(j1)-boa; + //obob=abo(j2)-boa; + exphua1 = EXP(-gp3 * (workspace->total_bond_order[i] - bo_ij->BO)); + exphub1 = EXP(-gp3 * (workspace->total_bond_order[j] - bo_ij->BO)); + //ovoab=abo(j1)-aval(it1)+abo(j2)-aval(it2); + exphuov = EXP(gp4 * (workspace->Delta[i] + workspace->Delta[j])); + hulpov = 1.0 / (1.0 + 25.0 * exphuov); + + estriph = gp10 * exphu * hulpov * (exphua1 + exphub1); + //estrain(j1) = estrain(j1) + 0.50*estriph; + //estrain(j2) = estrain(j2) + 0.50*estriph; + data->E_BE += estriph; + + decobdbo = gp10 * exphu * hulpov * (exphua1 + exphub1) * + ( gp3 - 2.0 * gp7 * (bo_ij->BO - 2.50) ); + decobdboua = -gp10 * exphu * hulpov * + (gp3 * exphua1 + 25.0 * gp4 * exphuov * hulpov * (exphua1 + exphub1)); + decobdboub = -gp10 * exphu * hulpov * + (gp3 * exphub1 + 25.0 * gp4 * exphuov * hulpov * (exphua1 + exphub1)); + + bo_ij->Cdbo += decobdbo; + workspace->CdDelta[i] += decobdboua; + workspace->CdDelta[j] += decobdboub; #ifdef TEST_ENERGY - fprintf( out_control->ebond, - "%6d%6d%24.15e%24.15e%24.15e%24.15e\n", - workspace->orig_id[i], workspace->orig_id[j], - //i+1, j+1, - estriph, decobdbo, decobdboua, decobdboub ); + fprintf( out_control->ebond, + "%6d%6d%24.15e%24.15e%24.15e%24.15e\n", + workspace->orig_id[i], workspace->orig_id[j], + //i+1, j+1, + estriph, decobdbo, decobdboua, decobdboub ); #endif #ifdef TEST_FORCES - Add_dBO( system, lists, i, pj, decobdbo, workspace->f_be ); - Add_dDelta( system, lists, i, decobdboua, workspace->f_be ); - Add_dDelta( system, lists, j, decobdboub, workspace->f_be ); + Add_dBO( system, lists, i, pj, decobdbo, workspace->f_be ); + Add_dDelta( system, lists, i, decobdboua, workspace->f_be ); + Add_dDelta( system, lists, j, decobdboub, workspace->f_be ); #endif - } - } - } - } + } + } + } + } } -void vdW_Coulomb_Energy( reax_system *system, control_params *control, - simulation_data *data, static_storage *workspace, - list **lists, output_controls *out_control ) +void vdW_Coulomb_Energy( reax_system *system, control_params *control, + simulation_data *data, static_storage *workspace, + list **lists, output_controls *out_control ) { - int i, j, pj; - int start_i, end_i; - real self_coef; - real p_vdW1, p_vdW1i; - real powr_vdW1, powgi_vdW1; - real tmp, r_ij, fn13, exp1, exp2; - real Tap, dTap, dfn13, CEvd, CEclmb; - real dr3gamij_1, dr3gamij_3; - real e_ele, e_vdW, e_core, de_core; - rvec temp, ext_press; - // rtensor temp_rtensor, total_rtensor; - two_body_parameters *twbp; - far_neighbor_data *nbr_pj; - list *far_nbrs; - - p_vdW1 = system->reaxprm.gp.l[28]; - p_vdW1i = 1.0 / p_vdW1; - far_nbrs = (*lists) + FAR_NBRS; - e_ele = 0; - e_vdW = 0; - e_core = 0; - de_core = 0; - - for( i = 0; i < system->N; ++i ) { - start_i = Start_Index(i, far_nbrs); - end_i = End_Index(i, far_nbrs); - // fprintf( stderr, "i: %d, start: %d, end: %d\n", - // i, start_i, end_i ); - - for( pj = start_i; pj < end_i; ++pj ) - if( far_nbrs->select.far_nbr_list[pj].d <= control->r_cut ) { - nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); - j = nbr_pj->nbr; - r_ij = nbr_pj->d; - twbp = &(system->reaxprm.tbp[ system->atoms[i].type ] - [ system->atoms[j].type ]); - self_coef = (i == j) ? 0.5 : 1.0; // for supporting small boxes! - - /* Calculate Taper and its derivative */ - // Tap = nbr_pj->Tap; -- precomputed during compte_H - Tap = control->Tap7 * r_ij + control->Tap6; - Tap = Tap * r_ij + control->Tap5; - Tap = Tap * r_ij + control->Tap4; - Tap = Tap * r_ij + control->Tap3; - Tap = Tap * r_ij + control->Tap2; - Tap = Tap * r_ij + control->Tap1; - Tap = Tap * r_ij + control->Tap0; - - dTap = 7*control->Tap7 * r_ij + 6*control->Tap6; - dTap = dTap * r_ij + 5*control->Tap5; - dTap = dTap * r_ij + 4*control->Tap4; - dTap = dTap * r_ij + 3*control->Tap3; - dTap = dTap * r_ij + 2*control->Tap2; - dTap += control->Tap1/r_ij; - - /*vdWaals Calculations*/ - if(system->reaxprm.gp.vdw_type==1 || system->reaxprm.gp.vdw_type==3) { - // shielding - powr_vdW1 = POW(r_ij, p_vdW1); - powgi_vdW1 = POW( 1.0 / twbp->gamma_w, p_vdW1); - - fn13 = POW( powr_vdW1 + powgi_vdW1, p_vdW1i ); - exp1 = EXP( twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); - exp2 = EXP( 0.5 * twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); - - data->E_vdW += e_vdW = - self_coef * Tap * twbp->D * (exp1 - 2.0 * exp2); - - dfn13 = POW( powr_vdW1 + powgi_vdW1, p_vdW1i - 1.0) * - POW(r_ij, p_vdW1 - 2.0); - - CEvd = self_coef * ( dTap * twbp->D * (exp1 - 2 * exp2) - - Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * - (exp1 - exp2) * dfn13 ); - } - else{ // no shielding - exp1 = EXP( twbp->alpha * (1.0 - r_ij / twbp->r_vdW) ); - exp2 = EXP( 0.5 * twbp->alpha * (1.0 - r_ij / twbp->r_vdW) ); - - data->E_vdW += e_vdW = - self_coef * Tap * twbp->D * (exp1 - 2.0 * exp2); - - CEvd = self_coef * ( dTap * twbp->D * (exp1 - 2.0 * exp2) - - Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * - (exp1 - exp2) ); - } - - if(system->reaxprm.gp.vdw_type==2 || system->reaxprm.gp.vdw_type==3) { - // innner wall - e_core = twbp->ecore * EXP(twbp->acore * (1.0-(r_ij/twbp->rcore))); - e_vdW += self_coef * Tap * e_core; - data->E_vdW += self_coef * Tap * e_core; - - de_core = -(twbp->acore/twbp->rcore) * e_core; - CEvd += self_coef * ( dTap * e_core + Tap * de_core ); - } - - /*Coulomb Calculations*/ - dr3gamij_1 = ( r_ij * r_ij * r_ij + twbp->gamma ); - dr3gamij_3 = POW( dr3gamij_1 , 0.33333333333333 ); - - tmp = Tap / dr3gamij_3; - //tmp = Tap * nbr_pj->inv_dr3gamij_3; -- precomputed during compte_H - data->E_Ele += e_ele = - self_coef * C_ele * system->atoms[i].q * system->atoms[j].q * tmp; - - - CEclmb = self_coef * C_ele * system->atoms[i].q * system->atoms[j].q * - ( dTap - Tap * r_ij / dr3gamij_1 ) / dr3gamij_3; - /*CEclmb = self_coef*C_ele*system->atoms[i].q*system->atoms[j].q* - ( dTap- Tap*r_ij*nbr_pj->inv_dr3gamij_1 )*nbr_pj->inv_dr3gamij_3;*/ - - - if( control->ensemble == NVE || control->ensemble == NVT || control->ensemble == bNVT ) { - rvec_ScaledAdd( system->atoms[i].f, - -(CEvd+CEclmb), nbr_pj->dvec ); - rvec_ScaledAdd( system->atoms[j].f, - +(CEvd+CEclmb), nbr_pj->dvec ); - } - else { // NPT, iNPT or sNPT - /* for pressure coupling, terms not related to bond order - derivatives are added directly into pressure vector/tensor */ - rvec_Scale( temp, CEvd + CEclmb, nbr_pj->dvec ); - - rvec_ScaledAdd( system->atoms[i].f, -1., temp ); - rvec_Add( system->atoms[j].f, temp ); - - rvec_iMultiply( ext_press, nbr_pj->rel_box, temp ); - rvec_Add( data->ext_press, ext_press ); - - /*fprintf( stderr, "nonbonded(%d,%d): rel_box (%f %f %f)", - i,j,nbr_pj->rel_box[0],nbr_pj->rel_box[1],nbr_pj->rel_box[2] ); - - fprintf( stderr, "force(%f %f %f)", temp[0], temp[1], temp[2] ); - - fprintf( stderr, "ext_press (%12.6f %12.6f %12.6f)\n", - data->ext_press[0], data->ext_press[1], data->ext_press[2] );*/ - - /* This part is intended for a fully-flexible box */ - /* rvec_OuterProduct( temp_rtensor, nbr_pj->dvec, - system->atoms[i].x ); - rtensor_Scale( total_rtensor, - F_C * -(CEvd + CEclmb), temp_rtensor ); - rvec_OuterProduct( temp_rtensor, - nbr_pj->dvec, system->atoms[j].x ); - rtensor_ScaledAdd( total_rtensor, - F_C * +(CEvd + CEclmb), temp_rtensor ); - - if( nbr_pj->imaginary ) - // This is an external force due to an imaginary nbr - rtensor_ScaledAdd( data->flex_bar.P, -1.0, total_rtensor ); - else - // This interaction is completely internal - rtensor_Add( data->flex_bar.P, total_rtensor ); */ - } - + int i, j, pj; + int start_i, end_i; + real self_coef; + real p_vdW1, p_vdW1i; + real powr_vdW1, powgi_vdW1; + real tmp, r_ij, fn13, exp1, exp2; + real Tap, dTap, dfn13, CEvd, CEclmb; + real dr3gamij_1, dr3gamij_3; + real e_ele, e_vdW, e_core, de_core; + rvec temp, ext_press; + // rtensor temp_rtensor, total_rtensor; + two_body_parameters *twbp; + far_neighbor_data *nbr_pj; + list *far_nbrs; + + p_vdW1 = system->reaxprm.gp.l[28]; + p_vdW1i = 1.0 / p_vdW1; + far_nbrs = (*lists) + FAR_NBRS; + e_ele = 0; + e_vdW = 0; + e_core = 0; + de_core = 0; + + for ( i = 0; i < system->N; ++i ) + { + start_i = Start_Index(i, far_nbrs); + end_i = End_Index(i, far_nbrs); + // fprintf( stderr, "i: %d, start: %d, end: %d\n", + // i, start_i, end_i ); + + for ( pj = start_i; pj < end_i; ++pj ) + if ( far_nbrs->select.far_nbr_list[pj].d <= control->r_cut ) + { + nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); + j = nbr_pj->nbr; + r_ij = nbr_pj->d; + twbp = &(system->reaxprm.tbp[ system->atoms[i].type ] + [ system->atoms[j].type ]); + self_coef = (i == j) ? 0.5 : 1.0; // for supporting small boxes! + + /* Calculate Taper and its derivative */ + // Tap = nbr_pj->Tap; -- precomputed during compte_H + Tap = control->Tap7 * r_ij + control->Tap6; + Tap = Tap * r_ij + control->Tap5; + Tap = Tap * r_ij + control->Tap4; + Tap = Tap * r_ij + control->Tap3; + Tap = Tap * r_ij + control->Tap2; + Tap = Tap * r_ij + control->Tap1; + Tap = Tap * r_ij + control->Tap0; + + dTap = 7 * control->Tap7 * r_ij + 6 * control->Tap6; + dTap = dTap * r_ij + 5 * control->Tap5; + dTap = dTap * r_ij + 4 * control->Tap4; + dTap = dTap * r_ij + 3 * control->Tap3; + dTap = dTap * r_ij + 2 * control->Tap2; + dTap += control->Tap1 / r_ij; + + /*vdWaals Calculations*/ + if (system->reaxprm.gp.vdw_type == 1 || system->reaxprm.gp.vdw_type == 3) + { + // shielding + powr_vdW1 = POW(r_ij, p_vdW1); + powgi_vdW1 = POW( 1.0 / twbp->gamma_w, p_vdW1); + + fn13 = POW( powr_vdW1 + powgi_vdW1, p_vdW1i ); + exp1 = EXP( twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); + exp2 = EXP( 0.5 * twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); + + data->E_vdW += e_vdW = + self_coef * Tap * twbp->D * (exp1 - 2.0 * exp2); + + dfn13 = POW( powr_vdW1 + powgi_vdW1, p_vdW1i - 1.0) * + POW(r_ij, p_vdW1 - 2.0); + + CEvd = self_coef * ( dTap * twbp->D * (exp1 - 2 * exp2) - + Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * + (exp1 - exp2) * dfn13 ); + } + else // no shielding + { + exp1 = EXP( twbp->alpha * (1.0 - r_ij / twbp->r_vdW) ); + exp2 = EXP( 0.5 * twbp->alpha * (1.0 - r_ij / twbp->r_vdW) ); + + data->E_vdW += e_vdW = + self_coef * Tap * twbp->D * (exp1 - 2.0 * exp2); + + CEvd = self_coef * ( dTap * twbp->D * (exp1 - 2.0 * exp2) - + Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * + (exp1 - exp2) ); + } + + if (system->reaxprm.gp.vdw_type == 2 || system->reaxprm.gp.vdw_type == 3) + { + // innner wall + e_core = twbp->ecore * EXP(twbp->acore * (1.0 - (r_ij / twbp->rcore))); + e_vdW += self_coef * Tap * e_core; + data->E_vdW += self_coef * Tap * e_core; + + de_core = -(twbp->acore / twbp->rcore) * e_core; + CEvd += self_coef * ( dTap * e_core + Tap * de_core ); + } + + /*Coulomb Calculations*/ + dr3gamij_1 = ( r_ij * r_ij * r_ij + twbp->gamma ); + dr3gamij_3 = POW( dr3gamij_1 , 0.33333333333333 ); + + tmp = Tap / dr3gamij_3; + //tmp = Tap * nbr_pj->inv_dr3gamij_3; -- precomputed during compte_H + data->E_Ele += e_ele = + self_coef * C_ele * system->atoms[i].q * system->atoms[j].q * tmp; + + + CEclmb = self_coef * C_ele * system->atoms[i].q * system->atoms[j].q * + ( dTap - Tap * r_ij / dr3gamij_1 ) / dr3gamij_3; + /*CEclmb = self_coef*C_ele*system->atoms[i].q*system->atoms[j].q* + ( dTap- Tap*r_ij*nbr_pj->inv_dr3gamij_1 )*nbr_pj->inv_dr3gamij_3;*/ + + + if ( control->ensemble == NVE || control->ensemble == NVT || control->ensemble == bNVT ) + { + rvec_ScaledAdd( system->atoms[i].f, + -(CEvd + CEclmb), nbr_pj->dvec ); + rvec_ScaledAdd( system->atoms[j].f, + +(CEvd + CEclmb), nbr_pj->dvec ); + } + else // NPT, iNPT or sNPT + { + /* for pressure coupling, terms not related to bond order + derivatives are added directly into pressure vector/tensor */ + rvec_Scale( temp, CEvd + CEclmb, nbr_pj->dvec ); + + rvec_ScaledAdd( system->atoms[i].f, -1., temp ); + rvec_Add( system->atoms[j].f, temp ); + + rvec_iMultiply( ext_press, nbr_pj->rel_box, temp ); + rvec_Add( data->ext_press, ext_press ); + + /*fprintf( stderr, "nonbonded(%d,%d): rel_box (%f %f %f)", + i,j,nbr_pj->rel_box[0],nbr_pj->rel_box[1],nbr_pj->rel_box[2] ); + + fprintf( stderr, "force(%f %f %f)", temp[0], temp[1], temp[2] ); + + fprintf( stderr, "ext_press (%12.6f %12.6f %12.6f)\n", + data->ext_press[0], data->ext_press[1], data->ext_press[2] );*/ + + /* This part is intended for a fully-flexible box */ + /* rvec_OuterProduct( temp_rtensor, nbr_pj->dvec, + system->atoms[i].x ); + rtensor_Scale( total_rtensor, + F_C * -(CEvd + CEclmb), temp_rtensor ); + rvec_OuterProduct( temp_rtensor, + nbr_pj->dvec, system->atoms[j].x ); + rtensor_ScaledAdd( total_rtensor, + F_C * +(CEvd + CEclmb), temp_rtensor ); + + if( nbr_pj->imaginary ) + // This is an external force due to an imaginary nbr + rtensor_ScaledAdd( data->flex_bar.P, -1.0, total_rtensor ); + else + // This interaction is completely internal + rtensor_Add( data->flex_bar.P, total_rtensor ); */ + } + #ifdef TEST_ENERGY - rvec_MakeZero( temp ); - rvec_ScaledAdd( temp, +CEvd, nbr_pj->dvec ); - fprintf( out_control->evdw, - "%6d%6d%24.15e%24.15e%24.15e%24.15e%24.15e\n", - //i+1, j+1, - MIN( workspace->orig_id[i], workspace->orig_id[j] ), - MAX( workspace->orig_id[i], workspace->orig_id[j] ), - r_ij, e_vdW, temp[0], temp[1], temp[2]/*, data->E_vdW*/ ); - - fprintf( out_control->ecou, "%6d%6d%24.15e%24.15e%24.15e%24.15e\n", - MIN( workspace->orig_id[i], workspace->orig_id[j] ), - MAX( workspace->orig_id[i], workspace->orig_id[j] ), - r_ij, system->atoms[i].q, system->atoms[j].q, - e_ele/*, data->E_Ele*/ ); + rvec_MakeZero( temp ); + rvec_ScaledAdd( temp, +CEvd, nbr_pj->dvec ); + fprintf( out_control->evdw, + "%6d%6d%24.15e%24.15e%24.15e%24.15e%24.15e\n", + //i+1, j+1, + MIN( workspace->orig_id[i], workspace->orig_id[j] ), + MAX( workspace->orig_id[i], workspace->orig_id[j] ), + r_ij, e_vdW, temp[0], temp[1], temp[2]/*, data->E_vdW*/ ); + + fprintf( out_control->ecou, "%6d%6d%24.15e%24.15e%24.15e%24.15e\n", + MIN( workspace->orig_id[i], workspace->orig_id[j] ), + MAX( workspace->orig_id[i], workspace->orig_id[j] ), + r_ij, system->atoms[i].q, system->atoms[j].q, + e_ele/*, data->E_Ele*/ ); #endif #ifdef TEST_FORCES - rvec_ScaledAdd( workspace->f_vdw[i], -CEvd, nbr_pj->dvec ); - rvec_ScaledAdd( workspace->f_vdw[j], +CEvd, nbr_pj->dvec ); - rvec_ScaledAdd( workspace->f_ele[i], -CEclmb, nbr_pj->dvec ); - rvec_ScaledAdd( workspace->f_ele[j], +CEclmb, nbr_pj->dvec ); + rvec_ScaledAdd( workspace->f_vdw[i], -CEvd, nbr_pj->dvec ); + rvec_ScaledAdd( workspace->f_vdw[j], +CEvd, nbr_pj->dvec ); + rvec_ScaledAdd( workspace->f_ele[i], -CEclmb, nbr_pj->dvec ); + rvec_ScaledAdd( workspace->f_ele[j], +CEclmb, nbr_pj->dvec ); #endif - } - } - - // fclose( fout ); - - // fprintf( stderr, "nonbonded: ext_press (%24.15e %24.15e %24.15e)\n", - // data->ext_press[0], data->ext_press[1], data->ext_press[2] ); + } + } + + // fclose( fout ); + + // fprintf( stderr, "nonbonded: ext_press (%24.15e %24.15e %24.15e)\n", + // data->ext_press[0], data->ext_press[1], data->ext_press[2] ); } -void LR_vdW_Coulomb( reax_system *system, control_params *control, - int i, int j, real r_ij, LR_data *lr ) +void LR_vdW_Coulomb( reax_system *system, control_params *control, + int i, int j, real r_ij, LR_data *lr ) { - real p_vdW1 = system->reaxprm.gp.l[28]; - real p_vdW1i = 1.0 / p_vdW1; - real powr_vdW1, powgi_vdW1; - real tmp, fn13, exp1, exp2; - real Tap, dTap, dfn13; - real dr3gamij_1, dr3gamij_3; - real e_core, de_core; - two_body_parameters *twbp; - - twbp = &(system->reaxprm.tbp[i][j]); - e_core = 0; - de_core = 0; - - /* calculate taper and its derivative */ - Tap = control->Tap7 * r_ij + control->Tap6; - Tap = Tap * r_ij + control->Tap5; - Tap = Tap * r_ij + control->Tap4; - Tap = Tap * r_ij + control->Tap3; - Tap = Tap * r_ij + control->Tap2; - Tap = Tap * r_ij + control->Tap1; - Tap = Tap * r_ij + control->Tap0; - - dTap = 7*control->Tap7 * r_ij + 6*control->Tap6; - dTap = dTap * r_ij + 5*control->Tap5; - dTap = dTap * r_ij + 4*control->Tap4; - dTap = dTap * r_ij + 3*control->Tap3; - dTap = dTap * r_ij + 2*control->Tap2; - dTap += control->Tap1/r_ij; - - - /* vdWaals calculations */ - powr_vdW1 = POW(r_ij, p_vdW1); - powgi_vdW1 = POW( 1.0 / twbp->gamma_w, p_vdW1); - - fn13 = POW( powr_vdW1 + powgi_vdW1, p_vdW1i ); - exp1 = EXP( twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); - exp2 = EXP( 0.5 * twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); - - lr->e_vdW = Tap * twbp->D * (exp1 - 2.0 * exp2); - /* fprintf(stderr,"vdW: Tap:%f, r: %f, f13:%f, D:%f, Energy:%f,\ - Gamma_w:%f, p_vdw: %f, alpha: %f, r_vdw: %f, %lf %lf\n", - Tap, r_ij, fn13, twbp->D, Tap * twbp->D * (exp1 - 2.0 * exp2), - powgi_vdW1, p_vdW1, twbp->alpha, twbp->r_vdW, exp1, exp2); */ - - dfn13 = POW( powr_vdW1 + powgi_vdW1, p_vdW1i - 1.0) * POW(r_ij, p_vdW1 - 2.0); - - lr->CEvd = dTap * twbp->D * (exp1 - 2 * exp2) - - Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * (exp1 - exp2) * dfn13; - - /*vdWaals Calculations*/ - if(system->reaxprm.gp.vdw_type==1 || system->reaxprm.gp.vdw_type==3) - { // shielding - powr_vdW1 = POW(r_ij, p_vdW1); - powgi_vdW1 = POW( 1.0 / twbp->gamma_w, p_vdW1); - - fn13 = POW( powr_vdW1 + powgi_vdW1, p_vdW1i ); - exp1 = EXP( twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); - exp2 = EXP( 0.5 * twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); - - lr->e_vdW = Tap * twbp->D * (exp1 - 2.0 * exp2); - - dfn13 = POW( powr_vdW1 + powgi_vdW1, p_vdW1i - 1.0) * - POW(r_ij, p_vdW1 - 2.0); - - lr->CEvd = dTap * twbp->D * (exp1 - 2.0 * exp2) - - Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * (exp1 - exp2) * dfn13; - } - else{ // no shielding - exp1 = EXP( twbp->alpha * (1.0 - r_ij / twbp->r_vdW) ); - exp2 = EXP( 0.5 * twbp->alpha * (1.0 - r_ij / twbp->r_vdW) ); - + real p_vdW1 = system->reaxprm.gp.l[28]; + real p_vdW1i = 1.0 / p_vdW1; + real powr_vdW1, powgi_vdW1; + real tmp, fn13, exp1, exp2; + real Tap, dTap, dfn13; + real dr3gamij_1, dr3gamij_3; + real e_core, de_core; + two_body_parameters *twbp; + + twbp = &(system->reaxprm.tbp[i][j]); + e_core = 0; + de_core = 0; + + /* calculate taper and its derivative */ + Tap = control->Tap7 * r_ij + control->Tap6; + Tap = Tap * r_ij + control->Tap5; + Tap = Tap * r_ij + control->Tap4; + Tap = Tap * r_ij + control->Tap3; + Tap = Tap * r_ij + control->Tap2; + Tap = Tap * r_ij + control->Tap1; + Tap = Tap * r_ij + control->Tap0; + + dTap = 7 * control->Tap7 * r_ij + 6 * control->Tap6; + dTap = dTap * r_ij + 5 * control->Tap5; + dTap = dTap * r_ij + 4 * control->Tap4; + dTap = dTap * r_ij + 3 * control->Tap3; + dTap = dTap * r_ij + 2 * control->Tap2; + dTap += control->Tap1 / r_ij; + + + /* vdWaals calculations */ + powr_vdW1 = POW(r_ij, p_vdW1); + powgi_vdW1 = POW( 1.0 / twbp->gamma_w, p_vdW1); + + fn13 = POW( powr_vdW1 + powgi_vdW1, p_vdW1i ); + exp1 = EXP( twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); + exp2 = EXP( 0.5 * twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); + lr->e_vdW = Tap * twbp->D * (exp1 - 2.0 * exp2); - - lr->CEvd = dTap * twbp->D * (exp1 - 2.0 * exp2) - - Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * (exp1 - exp2); - } - - if(system->reaxprm.gp.vdw_type==2 || system->reaxprm.gp.vdw_type==3) - { // innner wall - e_core = twbp->ecore * EXP(twbp->acore * (1.0-(r_ij/twbp->rcore))); - lr->e_vdW += Tap * e_core; - - de_core = -(twbp->acore/twbp->rcore) * e_core; - lr->CEvd += dTap * e_core + Tap * de_core; + /* fprintf(stderr,"vdW: Tap:%f, r: %f, f13:%f, D:%f, Energy:%f,\ + Gamma_w:%f, p_vdw: %f, alpha: %f, r_vdw: %f, %lf %lf\n", + Tap, r_ij, fn13, twbp->D, Tap * twbp->D * (exp1 - 2.0 * exp2), + powgi_vdW1, p_vdW1, twbp->alpha, twbp->r_vdW, exp1, exp2); */ + + dfn13 = POW( powr_vdW1 + powgi_vdW1, p_vdW1i - 1.0) * POW(r_ij, p_vdW1 - 2.0); + + lr->CEvd = dTap * twbp->D * (exp1 - 2 * exp2) - + Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * (exp1 - exp2) * dfn13; + + /*vdWaals Calculations*/ + if (system->reaxprm.gp.vdw_type == 1 || system->reaxprm.gp.vdw_type == 3) + { + // shielding + powr_vdW1 = POW(r_ij, p_vdW1); + powgi_vdW1 = POW( 1.0 / twbp->gamma_w, p_vdW1); + + fn13 = POW( powr_vdW1 + powgi_vdW1, p_vdW1i ); + exp1 = EXP( twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); + exp2 = EXP( 0.5 * twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); + + lr->e_vdW = Tap * twbp->D * (exp1 - 2.0 * exp2); + + dfn13 = POW( powr_vdW1 + powgi_vdW1, p_vdW1i - 1.0) * + POW(r_ij, p_vdW1 - 2.0); + + lr->CEvd = dTap * twbp->D * (exp1 - 2.0 * exp2) - + Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * (exp1 - exp2) * dfn13; + } + else // no shielding + { + exp1 = EXP( twbp->alpha * (1.0 - r_ij / twbp->r_vdW) ); + exp2 = EXP( 0.5 * twbp->alpha * (1.0 - r_ij / twbp->r_vdW) ); + + lr->e_vdW = Tap * twbp->D * (exp1 - 2.0 * exp2); + + lr->CEvd = dTap * twbp->D * (exp1 - 2.0 * exp2) - + Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * (exp1 - exp2); + } + + if (system->reaxprm.gp.vdw_type == 2 || system->reaxprm.gp.vdw_type == 3) + { + // innner wall + e_core = twbp->ecore * EXP(twbp->acore * (1.0 - (r_ij / twbp->rcore))); + lr->e_vdW += Tap * e_core; + + de_core = -(twbp->acore / twbp->rcore) * e_core; + lr->CEvd += dTap * e_core + Tap * de_core; } - - /* Coulomb calculations */ - dr3gamij_1 = ( r_ij * r_ij * r_ij + twbp->gamma ); - dr3gamij_3 = POW( dr3gamij_1 , 0.33333333333333 ); - - tmp = Tap / dr3gamij_3; - lr->H = EV_to_KCALpMOL * tmp; - lr->e_ele = C_ele * tmp; - /* fprintf( stderr,"i:%d(%d), j:%d(%d), gamma:%f,\ - Tap:%f, dr3gamij_3:%f, qi: %f, qj: %f\n", - i, system->atoms[i].type, j, system->atoms[j].type, - twbp->gamma, Tap, dr3gamij_3, - system->atoms[i].q, system->atoms[j].q ); */ - - lr->CEclmb = C_ele * ( dTap - Tap * r_ij / dr3gamij_1 ) / dr3gamij_3; - /* fprintf( stdout, "%d %d\t%g\t%g %g\t%g %g\t%g %g\n", - i+1, j+1, r_ij, e_vdW, CEvd * r_ij, - system->atoms[i].q, system->atoms[j].q, e_ele, CEclmb * r_ij ); */ - - /* fprintf( stderr,"LR_Lookup:%3d%3d%5.3f-%8.5f,%8.5f%8.5f,%8.5f%8.5f\n", - i, j, r_ij, lr->H, lr->e_vdW, lr->CEvd, lr->e_ele, lr->CEclmb ); */ + + /* Coulomb calculations */ + dr3gamij_1 = ( r_ij * r_ij * r_ij + twbp->gamma ); + dr3gamij_3 = POW( dr3gamij_1 , 0.33333333333333 ); + + tmp = Tap / dr3gamij_3; + lr->H = EV_to_KCALpMOL * tmp; + lr->e_ele = C_ele * tmp; + /* fprintf( stderr,"i:%d(%d), j:%d(%d), gamma:%f,\ + Tap:%f, dr3gamij_3:%f, qi: %f, qj: %f\n", + i, system->atoms[i].type, j, system->atoms[j].type, + twbp->gamma, Tap, dr3gamij_3, + system->atoms[i].q, system->atoms[j].q ); */ + + lr->CEclmb = C_ele * ( dTap - Tap * r_ij / dr3gamij_1 ) / dr3gamij_3; + /* fprintf( stdout, "%d %d\t%g\t%g %g\t%g %g\t%g %g\n", + i+1, j+1, r_ij, e_vdW, CEvd * r_ij, + system->atoms[i].q, system->atoms[j].q, e_ele, CEclmb * r_ij ); */ + + /* fprintf( stderr,"LR_Lookup:%3d%3d%5.3f-%8.5f,%8.5f%8.5f,%8.5f%8.5f\n", + i, j, r_ij, lr->H, lr->e_vdW, lr->CEvd, lr->e_ele, lr->CEclmb ); */ } void Tabulated_vdW_Coulomb_Energy( reax_system *system, control_params *control, - simulation_data *data, - static_storage *workspace, list **lists, - output_controls *out_control ) + simulation_data *data, + static_storage *workspace, list **lists, + output_controls *out_control ) { - int i, j, pj, r, steps, update_freq, update_energies; - int type_i, type_j, tmin, tmax; - int start_i, end_i; - real r_ij, self_coef, base, dif; - real e_vdW, e_ele; - real CEvd, CEclmb; - rvec temp, ext_press; - far_neighbor_data *nbr_pj; - list *far_nbrs = (*lists) + FAR_NBRS; - LR_lookup_table *t; - - steps = data->step - data->prev_steps; - update_freq = out_control->energy_update_freq; - update_energies = update_freq > 0 && steps % update_freq == 0; - - for( i = 0; i < system->N; ++i ) { - type_i = system->atoms[i].type; - start_i = Start_Index(i,far_nbrs); - end_i = End_Index(i,far_nbrs); - - for( pj = start_i; pj < end_i; ++pj ) - if( far_nbrs->select.far_nbr_list[pj].d <= control->r_cut ) { - nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); - j = nbr_pj->nbr; - type_j = system->atoms[j].type; - r_ij = nbr_pj->d; - self_coef = (i == j) ? 0.5 : 1.0; - tmin = MIN( type_i, type_j ); - tmax = MAX( type_i, type_j ); - t = &( LR[tmin][tmax] ); - - /* Cubic Spline Interpolation */ - r = (int)(r_ij * t->inv_dx); - if( r == 0 ) ++r; - base = (real)(r+1) * t->dx; - dif = r_ij - base; - //fprintf(stderr, "r: %f, i: %d, base: %f, dif: %f\n", r, i, base, dif); - - if( update_energies ) { - e_vdW = ((t->vdW[r].d*dif + t->vdW[r].c)*dif + t->vdW[r].b)*dif + - t->vdW[r].a; - e_vdW *= self_coef; - - e_ele = ((t->ele[r].d*dif + t->ele[r].c)*dif + t->ele[r].b)*dif + - t->ele[r].a; - e_ele *= self_coef * system->atoms[i].q * system->atoms[j].q; - - data->E_vdW += e_vdW; - data->E_Ele += e_ele; - } - - CEvd = ((t->CEvd[r].d*dif + t->CEvd[r].c)*dif + t->CEvd[r].b)*dif + - t->CEvd[r].a; - CEvd *= self_coef; - //CEvd = (3*t->vdW[r].d*dif + 2*t->vdW[r].c)*dif + t->vdW[r].b; - - CEclmb = ((t->CEclmb[r].d*dif+t->CEclmb[r].c)*dif+t->CEclmb[r].b)*dif + - t->CEclmb[r].a; - CEclmb *= self_coef * system->atoms[i].q * system->atoms[j].q; - - if( control->ensemble == NVE || control->ensemble == NVT || control->ensemble == bNVT) { - rvec_ScaledAdd( system->atoms[i].f, -(CEvd + CEclmb), nbr_pj->dvec ); - rvec_ScaledAdd( system->atoms[j].f, +(CEvd + CEclmb), nbr_pj->dvec ); - } - else { // NPT, iNPT or sNPT - /* for pressure coupling, terms not related to bond order - derivatives are added directly into pressure vector/tensor */ - rvec_Scale( temp, CEvd + CEclmb, nbr_pj->dvec ); - rvec_ScaledAdd( system->atoms[i].f, -1., temp ); - rvec_Add( system->atoms[j].f, temp ); - rvec_iMultiply( ext_press, nbr_pj->rel_box, temp ); - rvec_Add( data->ext_press, ext_press ); - } - + int i, j, pj, r, steps, update_freq, update_energies; + int type_i, type_j, tmin, tmax; + int start_i, end_i; + real r_ij, self_coef, base, dif; + real e_vdW, e_ele; + real CEvd, CEclmb; + rvec temp, ext_press; + far_neighbor_data *nbr_pj; + list *far_nbrs = (*lists) + FAR_NBRS; + LR_lookup_table *t; + + steps = data->step - data->prev_steps; + update_freq = out_control->energy_update_freq; + update_energies = update_freq > 0 && steps % update_freq == 0; + + for ( i = 0; i < system->N; ++i ) + { + type_i = system->atoms[i].type; + start_i = Start_Index(i, far_nbrs); + end_i = End_Index(i, far_nbrs); + + for ( pj = start_i; pj < end_i; ++pj ) + if ( far_nbrs->select.far_nbr_list[pj].d <= control->r_cut ) + { + nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); + j = nbr_pj->nbr; + type_j = system->atoms[j].type; + r_ij = nbr_pj->d; + self_coef = (i == j) ? 0.5 : 1.0; + tmin = MIN( type_i, type_j ); + tmax = MAX( type_i, type_j ); + t = &( LR[tmin][tmax] ); + + /* Cubic Spline Interpolation */ + r = (int)(r_ij * t->inv_dx); + if ( r == 0 ) ++r; + base = (real)(r + 1) * t->dx; + dif = r_ij - base; + //fprintf(stderr, "r: %f, i: %d, base: %f, dif: %f\n", r, i, base, dif); + + if ( update_energies ) + { + e_vdW = ((t->vdW[r].d * dif + t->vdW[r].c) * dif + t->vdW[r].b) * dif + + t->vdW[r].a; + e_vdW *= self_coef; + + e_ele = ((t->ele[r].d * dif + t->ele[r].c) * dif + t->ele[r].b) * dif + + t->ele[r].a; + e_ele *= self_coef * system->atoms[i].q * system->atoms[j].q; + + data->E_vdW += e_vdW; + data->E_Ele += e_ele; + } + + CEvd = ((t->CEvd[r].d * dif + t->CEvd[r].c) * dif + t->CEvd[r].b) * dif + + t->CEvd[r].a; + CEvd *= self_coef; + //CEvd = (3*t->vdW[r].d*dif + 2*t->vdW[r].c)*dif + t->vdW[r].b; + + CEclmb = ((t->CEclmb[r].d * dif + t->CEclmb[r].c) * dif + t->CEclmb[r].b) * dif + + t->CEclmb[r].a; + CEclmb *= self_coef * system->atoms[i].q * system->atoms[j].q; + + if ( control->ensemble == NVE || control->ensemble == NVT || control->ensemble == bNVT) + { + rvec_ScaledAdd( system->atoms[i].f, -(CEvd + CEclmb), nbr_pj->dvec ); + rvec_ScaledAdd( system->atoms[j].f, +(CEvd + CEclmb), nbr_pj->dvec ); + } + else // NPT, iNPT or sNPT + { + /* for pressure coupling, terms not related to bond order + derivatives are added directly into pressure vector/tensor */ + rvec_Scale( temp, CEvd + CEclmb, nbr_pj->dvec ); + rvec_ScaledAdd( system->atoms[i].f, -1., temp ); + rvec_Add( system->atoms[j].f, temp ); + rvec_iMultiply( ext_press, nbr_pj->rel_box, temp ); + rvec_Add( data->ext_press, ext_press ); + } + #ifdef TEST_ENERGY - fprintf(out_control->evdw, "%6d%6d%24.15e%24.15e%24.15e\n", - workspace->orig_id[i], workspace->orig_id[j], - r_ij, e_vdW, data->E_vdW ); - fprintf(out_control->ecou,"%6d%6d%24.15e%24.15e%24.15e%24.15e%24.15e\n", - workspace->orig_id[i], workspace->orig_id[j], - r_ij, system->atoms[i].q, system->atoms[j].q, - e_ele, data->E_Ele ); + fprintf(out_control->evdw, "%6d%6d%24.15e%24.15e%24.15e\n", + workspace->orig_id[i], workspace->orig_id[j], + r_ij, e_vdW, data->E_vdW ); + fprintf(out_control->ecou, "%6d%6d%24.15e%24.15e%24.15e%24.15e%24.15e\n", + workspace->orig_id[i], workspace->orig_id[j], + r_ij, system->atoms[i].q, system->atoms[j].q, + e_ele, data->E_Ele ); #endif #ifdef TEST_FORCES - rvec_ScaledAdd( workspace->f_vdw[i], -CEvd, nbr_pj->dvec ); - rvec_ScaledAdd( workspace->f_vdw[j], +CEvd, nbr_pj->dvec ); - rvec_ScaledAdd( workspace->f_ele[i], -CEclmb, nbr_pj->dvec ); - rvec_ScaledAdd( workspace->f_ele[j], +CEclmb, nbr_pj->dvec ); + rvec_ScaledAdd( workspace->f_vdw[i], -CEvd, nbr_pj->dvec ); + rvec_ScaledAdd( workspace->f_vdw[j], +CEvd, nbr_pj->dvec ); + rvec_ScaledAdd( workspace->f_ele[i], -CEclmb, nbr_pj->dvec ); + rvec_ScaledAdd( workspace->f_ele[j], +CEclmb, nbr_pj->dvec ); #endif - } - } + } + } } @@ -555,11 +574,11 @@ void Tabulated_vdW_Coulomb_Energy( reax_system *system, control_params *control, r = (int) p; prev = &( t->y[r] ); next = &( t->y[r+1] ); - + tmp = p - r; e_vdW = self_coef * (prev->e_vdW + tmp*(next->e_vdW - prev->e_vdW )); CEvd = self_coef * (prev->CEvd + tmp*(next->CEvd - prev->CEvd )); - + e_ele = self_coef * (prev->e_ele + tmp*(next->e_ele - prev->e_ele )); e_ele = e_ele * system->atoms[i].q * system->atoms[j].q; CEclmb = self_coef * (prev->CEclmb+tmp*(next->CEclmb - prev->CEclmb)); diff --git a/puremd_rc_1003/sPuReMD/two_body_interactions.h b/puremd_rc_1003/sPuReMD/two_body_interactions.h index 48438342..bee9779b 100644 --- a/puremd_rc_1003/sPuReMD/two_body_interactions.h +++ b/puremd_rc_1003/sPuReMD/two_body_interactions.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -24,11 +24,11 @@ #include <mytypes.h> -void Bond_Energy( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); +void Bond_Energy( reax_system*, control_params*, simulation_data*, + static_storage*, list**, output_controls* ); void vdW_Coulomb_Energy( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); + static_storage*, list**, output_controls* ); void LR_vdW_Coulomb( reax_system*, control_params*, int, int, real, LR_data* ); void Tabulated_vdW_Coulomb_Energy( reax_system*, control_params*, simulation_data*, - static_storage*, list**, output_controls* ); + static_storage*, list**, output_controls* ); #endif diff --git a/puremd_rc_1003/sPuReMD/vector.c b/puremd_rc_1003/sPuReMD/vector.c index d6bed7ae..b5eef5c6 100644 --- a/puremd_rc_1003/sPuReMD/vector.c +++ b/puremd_rc_1003/sPuReMD/vector.c @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ @@ -24,535 +24,535 @@ inline int Vector_isZero( const real * const v, const unsigned int k ) { - unsigned int i; + unsigned int i; - for( i=0; i<k; ++i ) - { - if( fabs( v[i] ) > ALMOST_ZERO ) + for ( i = 0; i < k; ++i ) { - return 0; + if ( fabs( v[i] ) > ALMOST_ZERO ) + { + return 0; + } } - } - - return 1; + + return 1; } inline void Vector_MakeZero( real * const v, const unsigned int k ) { - unsigned int i; + unsigned int i; - for( i=0; i<k; ++i ) - { - v[i] = ZERO; - } + for ( i = 0; i < k; ++i ) + { + v[i] = ZERO; + } } inline void Vector_Copy( real * const dest, const real * const v, const unsigned int k ) { - unsigned int i; + unsigned int i; - for( i=0; i<k; ++i ) - { - dest[i] = v[i]; - } + for ( i = 0; i < k; ++i ) + { + dest[i] = v[i]; + } } inline void Vector_Scale( real * const dest, const real c, const real * const v, const unsigned int k ) { - unsigned int i; + unsigned int i; - for( i=0; i<k; ++i ) - { - dest[i] = c * v[i]; - } + for ( i = 0; i < k; ++i ) + { + dest[i] = c * v[i]; + } } inline void Vector_Sum( real * const dest, const real c, const real * const v, const real d, - const real * const y, const unsigned int k ) + const real * const y, const unsigned int k ) { - unsigned int i; + unsigned int i; - for( i=0; i<k; ++i ) - { - dest[i] = c * v[i] + d * y[i]; - } + for ( i = 0; i < k; ++i ) + { + dest[i] = c * v[i] + d * y[i]; + } } inline void Vector_Add( real * const dest, const real c, const real * const v, const unsigned int k ) { - unsigned int i; + unsigned int i; - for( i=0; i<k; ++i ) - { - dest[i] += c * v[i]; - } + for ( i = 0; i < k; ++i ) + { + dest[i] += c * v[i]; + } } inline void Vector_Add2( real * const dest, const real * const v, const unsigned int k ) { - unsigned int i; + unsigned int i; - for( i=0; i<k; ++i ) - { - dest[i] += v[i]; - } + for ( i = 0; i < k; ++i ) + { + dest[i] += v[i]; + } } void Vector_Print( FILE * const fout, const char * const vname, const real * const v, - const unsigned int k ) + const unsigned int k ) { - unsigned int i; + unsigned int i; - fprintf( fout, "%s:\n", vname ); - for( i = 0; i < k; ++i ) - { - fprintf( fout, "%24.15e\n", v[i] ); - } - fprintf( fout, "\n" ); + fprintf( fout, "%s:\n", vname ); + for ( i = 0; i < k; ++i ) + { + fprintf( fout, "%24.15e\n", v[i] ); + } + fprintf( fout, "\n" ); } inline real Dot( const real * const v1, const real * const v2, const unsigned int k ) { - real ret = ZERO; - unsigned int i; + real ret = ZERO; + unsigned int i; - for( i=0; i<k; ++i ) - { - ret += v1[i] * v2[i]; - } + for ( i = 0; i < k; ++i ) + { + ret += v1[i] * v2[i]; + } - return ret; + return ret; } inline real Norm( const real * const v1, const unsigned int k ) { - real ret = ZERO; - unsigned int i; + real ret = ZERO; + unsigned int i; - for( i=0; i<k; ++i ) - { - ret += SQR( v1[i] ); - } + for ( i = 0; i < k; ++i ) + { + ret += SQR( v1[i] ); + } - return SQRT( ret ); + return SQRT( ret ); } inline void rvec_Copy( rvec dest, const rvec src ) { - dest[0] = src[0], dest[1] = src[1], dest[2] = src[2]; + dest[0] = src[0], dest[1] = src[1], dest[2] = src[2]; } inline void rvec_Scale( rvec ret, const real c, const rvec v ) { - ret[0] = c * v[0], ret[1] = c * v[1], ret[2] = c * v[2]; + ret[0] = c * v[0], ret[1] = c * v[1], ret[2] = c * v[2]; } inline void rvec_Add( rvec ret, const rvec v ) { - ret[0] += v[0], ret[1] += v[1], ret[2] += v[2]; + ret[0] += v[0], ret[1] += v[1], ret[2] += v[2]; } inline void rvec_ScaledAdd( rvec ret, const real c, const rvec v ) { - ret[0] += c * v[0], ret[1] += c * v[1], ret[2] += c * v[2]; + ret[0] += c * v[0], ret[1] += c * v[1], ret[2] += c * v[2]; } inline void rvec_Sum( rvec ret, const rvec v1 , const rvec v2 ) { - ret[0] = v1[0] + v2[0]; - ret[1] = v1[1] + v2[1]; - ret[2] = v1[2] + v2[2]; + ret[0] = v1[0] + v2[0]; + ret[1] = v1[1] + v2[1]; + ret[2] = v1[2] + v2[2]; } inline void rvec_ScaledSum( rvec ret, const real c1, const rvec v1, - const real c2, const rvec v2 ) + const real c2, const rvec v2 ) { - ret[0] = c1 * v1[0] + c2 * v2[0]; - ret[1] = c1 * v1[1] + c2 * v2[1]; - ret[2] = c1 * v1[2] + c2 * v2[2]; + ret[0] = c1 * v1[0] + c2 * v2[0]; + ret[1] = c1 * v1[1] + c2 * v2[1]; + ret[2] = c1 * v1[2] + c2 * v2[2]; } inline real rvec_Dot( const rvec v1, const rvec v2 ) { - return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; } inline real rvec_ScaledDot( const real c1, const rvec v1, - const real c2, const rvec v2 ) + const real c2, const rvec v2 ) { - return (c1*c2) * (v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]); + return (c1 * c2) * (v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]); } inline void rvec_Multiply( rvec r, const rvec v1, const rvec v2 ) { - r[0] = v1[0] * v2[0]; - r[1] = v1[1] * v2[1]; - r[2] = v1[2] * v2[2]; + r[0] = v1[0] * v2[0]; + r[1] = v1[1] * v2[1]; + r[2] = v1[2] * v2[2]; } inline void rvec_iMultiply( rvec r, const ivec v1, const rvec v2 ) { - r[0] = v1[0] * v2[0]; - r[1] = v1[1] * v2[1]; - r[2] = v1[2] * v2[2]; + r[0] = v1[0] * v2[0]; + r[1] = v1[1] * v2[1]; + r[2] = v1[2] * v2[2]; } inline void rvec_Divide( rvec r, const rvec v1, const rvec v2 ) { - r[0] = v1[0] / v2[0]; - r[1] = v1[1] / v2[1]; - r[2] = v1[2] / v2[2]; + r[0] = v1[0] / v2[0]; + r[1] = v1[1] / v2[1]; + r[2] = v1[2] / v2[2]; } inline void rvec_iDivide( rvec r, const rvec v1, const ivec v2 ) { - r[0] = v1[0] / v2[0]; - r[1] = v1[1] / v2[1]; - r[2] = v1[2] / v2[2]; + r[0] = v1[0] / v2[0]; + r[1] = v1[1] / v2[1]; + r[2] = v1[2] / v2[2]; } inline void rvec_Invert( rvec r, const rvec v ) { - r[0] = 1. / v[0]; - r[1] = 1. / v[1]; - r[2] = 1. / v[2]; + r[0] = 1. / v[0]; + r[1] = 1. / v[1]; + r[2] = 1. / v[2]; } inline void rvec_Cross( rvec ret, const rvec v1, const rvec v2 ) { - ret[0] = v1[1] * v2[2] - v1[2] * v2[1]; - ret[1] = v1[2] * v2[0] - v1[0] * v2[2]; - ret[2] = v1[0] * v2[1] - v1[1] * v2[0]; + ret[0] = v1[1] * v2[2] - v1[2] * v2[1]; + ret[1] = v1[2] * v2[0] - v1[0] * v2[2]; + ret[2] = v1[0] * v2[1] - v1[1] * v2[0]; } inline void rvec_OuterProduct( rtensor r, const rvec v1, const rvec v2 ) { - unsigned int i, j; + unsigned int i, j; - for( i = 0; i < 3; ++i ) - { - for( j = 0; j < 3; ++j ) + for ( i = 0; i < 3; ++i ) { - r[i][j] = v1[i] * v2[j]; + for ( j = 0; j < 3; ++j ) + { + r[i][j] = v1[i] * v2[j]; + } } - } } inline real rvec_Norm_Sqr( const rvec v ) { - return SQR(v[0]) + SQR(v[1]) + SQR(v[2]); + return SQR(v[0]) + SQR(v[1]) + SQR(v[2]); } inline real rvec_Norm( const rvec v ) { - return SQRT( SQR(v[0]) + SQR(v[1]) + SQR(v[2]) ); + return SQRT( SQR(v[0]) + SQR(v[1]) + SQR(v[2]) ); } inline int rvec_isZero( const rvec v ) { - if( fabs(v[0]) > ALMOST_ZERO || - fabs(v[1]) > ALMOST_ZERO || - fabs(v[2]) > ALMOST_ZERO ) - { - return 0; - } - return 1; + if ( fabs(v[0]) > ALMOST_ZERO || + fabs(v[1]) > ALMOST_ZERO || + fabs(v[2]) > ALMOST_ZERO ) + { + return 0; + } + return 1; } inline void rvec_MakeZero( rvec v ) { - v[0] = v[1] = v[2] = ZERO; + v[0] = v[1] = v[2] = ZERO; } inline void rvec_Random( rvec v ) { - v[0] = Random(2.0)-1.0; - v[1] = Random(2.0)-1.0; - v[2] = Random(2.0)-1.0; + v[0] = Random(2.0) - 1.0; + v[1] = Random(2.0) - 1.0; + v[2] = Random(2.0) - 1.0; } inline void rtensor_Multiply( rtensor ret, rtensor m1, rtensor m2 ) { - unsigned int i, j, k; - rtensor temp; + unsigned int i, j, k; + rtensor temp; - // check if the result matrix is the same as one of m1, m2. - // if so, we cannot modify the contents of m1 or m2, so - // we have to use a temp matrix. - if( ret == m1 || ret == m2 ) + // check if the result matrix is the same as one of m1, m2. + // if so, we cannot modify the contents of m1 or m2, so + // we have to use a temp matrix. + if ( ret == m1 || ret == m2 ) { - for( i = 0; i < 3; ++i ) - for( j = 0; j < 3; ++j ) - { - temp[i][j] = 0; - for( k = 0; k < 3; ++k ) - temp[i][j] += m1[i][k] * m2[k][j]; - } - - for( i = 0; i < 3; ++i ) - for( j = 0; j < 3; ++j ) - ret[i][j] = temp[i][j]; + for ( i = 0; i < 3; ++i ) + for ( j = 0; j < 3; ++j ) + { + temp[i][j] = 0; + for ( k = 0; k < 3; ++k ) + temp[i][j] += m1[i][k] * m2[k][j]; + } + + for ( i = 0; i < 3; ++i ) + for ( j = 0; j < 3; ++j ) + ret[i][j] = temp[i][j]; } - else + else { - for( i = 0; i < 3; ++i ) - for( j = 0; j < 3; ++j ) - { - ret[i][j] = 0; - for( k = 0; k < 3; ++k ) - ret[i][j] += m1[i][k] * m2[k][j]; - } + for ( i = 0; i < 3; ++i ) + for ( j = 0; j < 3; ++j ) + { + ret[i][j] = 0; + for ( k = 0; k < 3; ++k ) + ret[i][j] += m1[i][k] * m2[k][j]; + } } } inline void rtensor_MatVec( rvec ret, rtensor m, const rvec v ) { - unsigned int i; - rvec temp; + unsigned int i; + rvec temp; - // if ret is the same vector as v, we cannot modify the - // contents of v until all computation is finished. - if( ret == v ) - { - for( i = 0; i < 3; ++i ) + // if ret is the same vector as v, we cannot modify the + // contents of v until all computation is finished. + if ( ret == v ) { - temp[i] = m[i][0] * v[0] + m[i][1] * v[1] + m[i][2] * v[2]; + for ( i = 0; i < 3; ++i ) + { + temp[i] = m[i][0] * v[0] + m[i][1] * v[1] + m[i][2] * v[2]; + } + + for ( i = 0; i < 3; ++i ) + { + ret[i] = temp[i]; + } } - - for( i = 0; i < 3; ++i ) + else { - ret[i] = temp[i]; + for ( i = 0; i < 3; ++i ) + { + ret[i] = m[i][0] * v[0] + m[i][1] * v[1] + m[i][2] * v[2]; + } } - } - else - { - for( i = 0; i < 3; ++i ) - { - ret[i] = m[i][0] * v[0] + m[i][1] * v[1] + m[i][2] * v[2]; - } - } } inline void rtensor_Scale( rtensor ret, const real c, rtensor m ) { - unsigned int i, j; + unsigned int i, j; - for( i = 0; i < 3; ++i ) - { - for( j = 0; j < 3; ++j ) + for ( i = 0; i < 3; ++i ) { - ret[i][j] = c * m[i][j]; + for ( j = 0; j < 3; ++j ) + { + ret[i][j] = c * m[i][j]; + } } - } } inline void rtensor_Add( rtensor ret, rtensor t ) { - int i, j; + int i, j; - for( i = 0; i < 3; ++i ) - { - for( j = 0; j < 3; ++j ) + for ( i = 0; i < 3; ++i ) { - ret[i][j] += t[i][j]; + for ( j = 0; j < 3; ++j ) + { + ret[i][j] += t[i][j]; + } } - } } inline void rtensor_ScaledAdd( rtensor ret, const real c, rtensor t ) { - unsigned int i, j; + unsigned int i, j; - for( i = 0; i < 3; ++i ) - { - for( j = 0; j < 3; ++j ) + for ( i = 0; i < 3; ++i ) { - ret[i][j] += c * t[i][j]; + for ( j = 0; j < 3; ++j ) + { + ret[i][j] += c * t[i][j]; + } } - } } inline void rtensor_Sum( rtensor ret, rtensor t1, rtensor t2 ) { - unsigned int i, j; + unsigned int i, j; - for( i = 0; i < 3; ++i ) - { - for( j = 0; j < 3; ++j ) + for ( i = 0; i < 3; ++i ) { - ret[i][j] = t1[i][j] + t2[i][j]; + for ( j = 0; j < 3; ++j ) + { + ret[i][j] = t1[i][j] + t2[i][j]; + } } - } } -inline void rtensor_ScaledSum( rtensor ret, const real c1, rtensor t1, - const real c2, rtensor t2 ) +inline void rtensor_ScaledSum( rtensor ret, const real c1, rtensor t1, + const real c2, rtensor t2 ) { - unsigned int i, j; + unsigned int i, j; - for( i = 0; i < 3; ++i ) - { - for( j = 0; j < 3; ++j ) + for ( i = 0; i < 3; ++i ) { - ret[i][j] = c1 * t1[i][j] + c2 * t2[i][j]; + for ( j = 0; j < 3; ++j ) + { + ret[i][j] = c1 * t1[i][j] + c2 * t2[i][j]; + } } - } } inline void rtensor_Copy( rtensor ret, rtensor t ) { - unsigned int i, j; + unsigned int i, j; - for( i = 0; i < 3; ++i ) - { - for( j = 0; j < 3; ++j ) + for ( i = 0; i < 3; ++i ) { - ret[i][j] = t[i][j]; + for ( j = 0; j < 3; ++j ) + { + ret[i][j] = t[i][j]; + } } - } } inline void rtensor_Identity( rtensor t ) { - t[0][0] = t[1][1] = t[2][2] = 1; - t[0][1] = t[0][2] = t[1][0] = t[1][2] = t[2][0] = t[2][1] = ZERO; + t[0][0] = t[1][1] = t[2][2] = 1; + t[0][1] = t[0][2] = t[1][0] = t[1][2] = t[2][0] = t[2][1] = ZERO; } inline void rtensor_MakeZero( rtensor t ) { - t[0][0] = t[0][1] = t[0][2] = ZERO; - t[1][0] = t[1][1] = t[1][2] = ZERO; - t[2][0] = t[2][1] = t[2][2] = ZERO; + t[0][0] = t[0][1] = t[0][2] = ZERO; + t[1][0] = t[1][1] = t[1][2] = ZERO; + t[2][0] = t[2][1] = t[2][2] = ZERO; } inline void rtensor_Transpose( rtensor ret, rtensor t ) { - ret[0][0] = t[0][0], ret[1][1] = t[1][1], ret[2][2] = t[2][2]; - ret[0][1] = t[1][0], ret[0][2] = t[2][0]; - ret[1][0] = t[0][1], ret[1][2] = t[2][1]; - ret[2][0] = t[0][2], ret[2][1] = t[1][2]; + ret[0][0] = t[0][0], ret[1][1] = t[1][1], ret[2][2] = t[2][2]; + ret[0][1] = t[1][0], ret[0][2] = t[2][0]; + ret[1][0] = t[0][1], ret[1][2] = t[2][1]; + ret[2][0] = t[0][2], ret[2][1] = t[1][2]; } inline real rtensor_Det( rtensor t ) { - return ( t[0][0] * (t[1][1] * t[2][2] - t[1][2] * t[2][1] ) + - t[0][1] * (t[1][2] * t[2][0] - t[1][0] * t[2][2] ) + - t[0][2] * (t[1][0] * t[2][1] - t[1][1] * t[2][0] ) ); + return ( t[0][0] * (t[1][1] * t[2][2] - t[1][2] * t[2][1] ) + + t[0][1] * (t[1][2] * t[2][0] - t[1][0] * t[2][2] ) + + t[0][2] * (t[1][0] * t[2][1] - t[1][1] * t[2][0] ) ); } inline real rtensor_Trace( rtensor t ) { - return (t[0][0] + t[1][1] + t[2][2]); + return (t[0][0] + t[1][1] + t[2][2]); } void Print_rTensor(FILE * const fp, rtensor t) { - unsigned int i, j; + unsigned int i, j; - for (i=0; i < 3; i++) + for (i = 0; i < 3; i++) { - fprintf(fp,"["); - for (j=0; j < 3; j++) - fprintf(fp,"%8.3f,\t",t[i][j]); - fprintf(fp,"]\n"); + fprintf(fp, "["); + for (j = 0; j < 3; j++) + fprintf(fp, "%8.3f,\t", t[i][j]); + fprintf(fp, "]\n"); } } inline void ivec_MakeZero( ivec v ) { - v[0] = v[1] = v[2] = 0; + v[0] = v[1] = v[2] = 0; } inline void ivec_Copy( ivec dest, const ivec src ) { - dest[0] = src[0], dest[1] = src[1], dest[2] = src[2]; + dest[0] = src[0], dest[1] = src[1], dest[2] = src[2]; } inline void ivec_Scale( ivec dest, const real C, const ivec src ) { - dest[0] = C * src[0]; - dest[1] = C * src[1]; - dest[2] = C * src[2]; + dest[0] = C * src[0]; + dest[1] = C * src[1]; + dest[2] = C * src[2]; } inline void ivec_rScale( ivec dest, const real C, const rvec src ) { - dest[0] = (int)(C * src[0]); - dest[1] = (int)(C * src[1]); - dest[2] = (int)(C * src[2]); + dest[0] = (int)(C * src[0]); + dest[1] = (int)(C * src[1]); + dest[2] = (int)(C * src[2]); } inline int ivec_isZero( const ivec v ) { - if( v[0]==0 && v[1]==0 && v[2]==0 ) - { - return 1; - } - return 0; + if ( v[0] == 0 && v[1] == 0 && v[2] == 0 ) + { + return 1; + } + return 0; } inline int ivec_isEqual( const ivec v1, const ivec v2 ) { - if( v1[0]==v2[0] && v1[1]==v2[1] && v1[2]==v2[2] ) - { - return 1; - } + if ( v1[0] == v2[0] && v1[1] == v2[1] && v1[2] == v2[2] ) + { + return 1; + } - return 0; + return 0; } inline void ivec_Sum( ivec dest, const ivec v1, const ivec v2 ) { - dest[0] = v1[0] + v2[0]; - dest[1] = v1[1] + v2[1]; - dest[2] = v1[2] + v2[2]; + dest[0] = v1[0] + v2[0]; + dest[1] = v1[1] + v2[1]; + dest[2] = v1[2] + v2[2]; } diff --git a/puremd_rc_1003/sPuReMD/vector.h b/puremd_rc_1003/sPuReMD/vector.h index 58b94180..68fd4892 100644 --- a/puremd_rc_1003/sPuReMD/vector.h +++ b/puremd_rc_1003/sPuReMD/vector.h @@ -1,20 +1,20 @@ /*---------------------------------------------------------------------- SerialReax - Reax Force Field Simulator - + Copyright (2010) Purdue University Hasan Metin Aktulga, haktulga@cs.purdue.edu Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of + published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details: <http://www.gnu.org/licenses/>. ----------------------------------------------------------------------*/ -- GitLab