Пример #1
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.;
}
/* 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.;
}