Exemplo n.º 1
0
void Reset_Pressures( simulation_data *data )
{
  data->flex_bar.P_scalar = 0;
  rtensor_MakeZero( data->flex_bar.P );

  data->iso_bar.P = 0;
  rvec_MakeZero( data->int_press );
  rvec_MakeZero( data->my_ext_press );
  rvec_MakeZero( data->ext_press );
}
Exemplo n.º 2
0
void Generate_Initial_Velocities( reax_system *system, real T )
{
  int i;
  real m, scale, norm;
  
  
  if( T <= 0.1 ) {
    for( i = 0; i < system->n; i++ )
      rvec_MakeZero( system->my_atoms[i].v );
  }
  else {
    Randomize();
    
    for( i = 0; i < system->n; i++ ) {
      rvec_Random( system->my_atoms[i].v );
      
      norm = rvec_Norm_Sqr( system->my_atoms[i].v );
      m = system->reax_param.sbp[ system->my_atoms[i].type ].mass;
      scale = sqrt( m * norm / (3.0 * K_B * T) );
      
      rvec_Scale( system->my_atoms[i].v, 1./scale, system->my_atoms[i].v );
      
      // fprintf( stderr, "v = %f %f %f\n", 
      // system->my_atoms[i].v[0], 
      // system->my_atoms[i].v[1], 
      // system->my_atoms[i].v[2] );      
      
      // fprintf( stderr, "scale = %f\n", scale );
      // fprintf( stderr, "v = %f %f %f\n", 
      // system->my_atoms[i].v[0], 
      // system->my_atoms[i].v[1], 
      // system->my_atoms[i].v[2] );
    }
  }
}
Exemplo n.º 3
0
/************************ initialize system ************************/
int Reposition_Atoms( reax_system *system, control_params *control, 
		      simulation_data *data, mpi_datatypes *mpi_data, 
		      char *msg )
{
  int   i;
  rvec  dx;
  
  /* reposition atoms */
  if( control->reposition_atoms == 0 ) { //fit atoms to periodic box
    rvec_MakeZero( dx );
  }
  else if( control->reposition_atoms == 1 ) { //put center of mass to center
    rvec_Scale( dx, 0.5, system->big_box.box_norms );
    rvec_ScaledAdd( dx, -1., data->xcm );
  }
  else if( control->reposition_atoms == 2 ) { //put center of mass to origin
    rvec_Scale( dx, -1., data->xcm );
  }
  else {
    strcpy( msg, "reposition_atoms: invalid option" );
    return FAILURE;
  }
  
  for( i = 0; i < system->n; ++i )
    // Inc_on_T3_Gen( system->my_atoms[i].x, dx, &(system->big_box) );
    rvec_Add( system->my_atoms[i].x, dx );

  return SUCCESS;
}
Exemplo n.º 4
0
void Compute_Pressure(reax_system* system, control_params *control,
                      simulation_data* data, mpi_datatypes *mpi_data)
{
  int i;
  reax_atom *p_atom;
  rvec tmp, tx, int_press;
  simulation_box *big_box = &(system->big_box);

  /* Calculate internal pressure */
  rvec_MakeZero( 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->my_atoms[i] );

      /* transform x into unitbox coordinates */
      Transform_to_UnitBox( p_atom->x, big_box, 1, tx );

      /* this atom's contribution to internal pressure */
      rvec_Multiply( tmp, p_atom->f, tx );
      rvec_Add( int_press, tmp );

    }
  }

  /* sum up internal and external pressure */
  MPI_Allreduce( int_press, data->int_press,
                 3, MPI_DOUBLE, MPI_SUM, mpi_data->comm_mesh3D );
  MPI_Allreduce( data->my_ext_press, data->ext_press,
                 3, MPI_DOUBLE, MPI_SUM, mpi_data->comm_mesh3D );

  /* kinetic contribution */
  data->kin_press = 2.*(E_CONV*data->sys_en.e_kin) / (3.*big_box->V*P_CONV);

  /* Calculate total pressure in each direction */
  data->tot_press[0] = data->kin_press -
    (( data->int_press[0] + data->ext_press[0] ) /
     ( big_box->box_norms[1] * big_box->box_norms[2] * P_CONV ));

  data->tot_press[1] = data->kin_press -
    (( data->int_press[1] + data->ext_press[1] ) /
     ( big_box->box_norms[0] * big_box->box_norms[2] * P_CONV ));

  data->tot_press[2] = data->kin_press -
    (( data->int_press[2] + data->ext_press[2] ) /
     ( big_box->box_norms[0] * big_box->box_norms[1] * P_CONV ));

  data->iso_bar.P =
    ( data->tot_press[0] + data->tot_press[1] + data->tot_press[2] ) / 3.;
}
Exemplo n.º 5
0
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 );
}
Exemplo n.º 6
0
void Compute_Center_of_Mass( reax_system *system, simulation_data *data,
                             mpi_datatypes *mpi_data, MPI_Comm comm )
{
  int i;
  double m, det; //xx, xy, xz, yy, yz, zz;
  double tmp_mat[6], tot_mat[6];
  rvec my_xcm, my_vcm, my_amcm, my_avcm;
  rvec tvec, diff;
  rtensor mat, inv;

  rvec_MakeZero( my_xcm );  // position of CoM
  rvec_MakeZero( my_vcm );  // velocity of CoM
  rvec_MakeZero( my_amcm ); // angular momentum of CoM
  rvec_MakeZero( my_avcm ); // angular velocity of CoM

  /* Compute the position, vel. and ang. momentum about the centre of mass */
  for( i = 0; i < system->n; ++i ) {
    m = system->reax_param.sbp[ system->my_atoms[i].type ].mass;

    rvec_ScaledAdd( my_xcm, m, system->my_atoms[i].x );
    rvec_ScaledAdd( my_vcm, m, system->my_atoms[i].v );

    rvec_Cross( tvec, system->my_atoms[i].x, system->my_atoms[i].v );
    rvec_ScaledAdd( my_amcm, m, tvec );
  }

  MPI_Allreduce( my_xcm, data->xcm, 3, MPI_DOUBLE, MPI_SUM, comm );
  MPI_Allreduce( my_vcm, data->vcm, 3, MPI_DOUBLE, MPI_SUM, comm );
  MPI_Allreduce( my_amcm, data->amcm, 3, MPI_DOUBLE, MPI_SUM, comm );

  rvec_Scale( data->xcm, data->inv_M, data->xcm );
  rvec_Scale( data->vcm, data->inv_M, data->vcm );
  rvec_Cross( tvec, data->xcm, data->vcm );
  rvec_ScaledAdd( data->amcm, -data->M, tvec );
  data->etran_cm = 0.5 * data->M * rvec_Norm_Sqr( data->vcm );

  /* Calculate and then invert the inertial tensor */
  for( i = 0; i < 6; ++i )
    tmp_mat[i] = 0;
  //my_xx = my_xy = my_xz = my_yy = my_yz = my_zz = 0;

  for( i = 0; i < system->n; ++i ){
    m = system->reax_param.sbp[ system->my_atoms[i].type ].mass;
    rvec_ScaledSum( diff, 1., system->my_atoms[i].x, -1., data->xcm );

    tmp_mat[0]/*my_xx*/ += diff[0] * diff[0] * m;
    tmp_mat[1]/*my_xy*/ += diff[0] * diff[1] * m;
    tmp_mat[2]/*my_xz*/ += diff[0] * diff[2] * m;
    tmp_mat[3]/*my_yy*/ += diff[1] * diff[1] * m;
    tmp_mat[4]/*my_yz*/ += diff[1] * diff[2] * m;
    tmp_mat[5]/*my_zz*/ += diff[2] * diff[2] * m;
  }

  MPI_Reduce( tmp_mat, tot_mat, 6, MPI_DOUBLE, MPI_SUM, MASTER_NODE, comm );

  if( system->my_rank == MASTER_NODE ) {
    mat[0][0] = tot_mat[3] + tot_mat[5];  // yy + zz;
    mat[0][1] = mat[1][0] = -tot_mat[1];  // -xy;
    mat[0][2] = mat[2][0] = -tot_mat[2];  // -xz;
    mat[1][1] = tot_mat[0] + tot_mat[5];  // xx + zz;
    mat[2][1] = mat[1][2] = -tot_mat[4];  // -yz;
    mat[2][2] = tot_mat[0] + tot_mat[3];  // xx + yy;

    /* invert the inertial tensor */
    det = ( mat[0][0] * mat[1][1] * mat[2][2] +
            mat[0][1] * mat[1][2] * mat[2][0] +
            mat[0][2] * mat[1][0] * mat[2][1] ) -
      ( mat[0][0] * mat[1][2] * mat[2][1] +
        mat[0][1] * mat[1][0] * mat[2][2] +
        mat[0][2] * mat[1][1] * mat[2][0] );

    inv[0][0] = mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1];
    inv[0][1] = mat[0][2] * mat[2][1] - mat[0][1] * mat[2][2];
    inv[0][2] = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1];
    inv[1][0] = mat[1][2] * mat[2][0] - mat[1][0] * mat[2][2];
    inv[1][1] = mat[0][0] * mat[2][2] - mat[0][2] * mat[2][0];
    inv[1][2] = mat[0][2] * mat[1][0] - mat[0][0] * mat[1][2];
    inv[2][0] = mat[1][0] * mat[2][1] - mat[2][0] * mat[1][1];
    inv[2][1] = mat[2][0] * mat[0][1] - mat[0][0] * mat[2][1];
    inv[2][2] = mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1];

    if( det > ALMOST_ZERO )
      rtensor_Scale( inv, 1./det, inv );
    else rtensor_MakeZero( inv );

    /* Compute the angular velocity about the centre of mass */
    rtensor_MatVec( data->avcm, inv, data->amcm );
  }

  MPI_Bcast( data->avcm, 3, MPI_DOUBLE, MASTER_NODE, comm );

  /* Compute the rotational energy */
  data->erot_cm = 0.5 * E_CONV * rvec_Dot( data->avcm, data->amcm );

}
/* IMPORTANT: This function assumes that current kinetic energy
 * the system is already computed
 *
 * 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, control_params *control,
                      simulation_data* data, mpi_datatypes *mpi_data)
{
  int i;
  reax_atom *p_atom;
  rvec tmp, tx, int_press;
  simulation_box *big_box = &(system->big_box);

  /* Calculate internal pressure */
  rvec_MakeZero( 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->my_atoms[i] );

      /* transform x into unitbox coordinates */
      Transform_to_UnitBox( p_atom->x, big_box, 1, tx );

      /* this atom's contribution to internal pressure */
      rvec_Multiply( tmp, p_atom->f, tx );
      rvec_Add( int_press, tmp );

#if defined(DEBUG)
      fprintf( stderr, "%8d%8.2f%8.2f%8.2f",
               i+1, p_atom->x[0], p_atom->x[1], p_atom->x[2] );
      fprintf( stderr, "%8.2f%8.2f%8.2f",
               p_atom->f[0], p_atom->f[1], p_atom->f[2] );
      fprintf( stderr, "%8.2f%8.2f%8.2f\n",
               int_press[0], int_press[1], int_press[2] );
#endif
    }
  }

  /* sum up internal and external pressure */
#if defined(DEBUG)
  fprintf(stderr,"p%d:p_int(%10.5f %10.5f %10.5f)p_ext(%10.5f %10.5f %10.5f)\n",
          system->my_rank, int_press[0], int_press[1], int_press[2],
          data->my_ext_press[0], data->my_ext_press[1], data->my_ext_press[2] );
#endif
  MPI_Allreduce( int_press, data->int_press,
                 3, MPI_DOUBLE, MPI_SUM, mpi_data->comm_mesh3D );
  MPI_Allreduce( data->my_ext_press, data->ext_press,
                 3, MPI_DOUBLE, MPI_SUM, mpi_data->comm_mesh3D );
#if defined(DEBUG)
  fprintf( stderr, "p%d: %10.5f %10.5f %10.5f\n",
           system->my_rank,
           data->int_press[0], data->int_press[1], data->int_press[2] );
  fprintf( stderr, "p%d: %10.5f %10.5f %10.5f\n",
           system->my_rank,
           data->ext_press[0], data->ext_press[1], data->ext_press[2] );
#endif

  /* kinetic contribution */
  data->kin_press = 2.*(E_CONV*data->sys_en.e_kin) / (3.*big_box->V*P_CONV);

  /* Calculate total pressure in each direction */
  data->tot_press[0] = data->kin_press -
    (( data->int_press[0] + data->ext_press[0] ) /
     ( big_box->box_norms[1] * big_box->box_norms[2] * P_CONV ));

  data->tot_press[1] = data->kin_press -
    (( data->int_press[1] + data->ext_press[1] ) /
     ( big_box->box_norms[0] * big_box->box_norms[2] * P_CONV ));

  data->tot_press[2] = data->kin_press -
    (( data->int_press[2] + data->ext_press[2] ) /
     ( big_box->box_norms[0] * big_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.;
}