Пример #1
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] );
    }
  }
}
Пример #2
0
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];

  for( i = 0; i < MAX_ATOM_TYPES; ++i )
    {
      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] = workspace->x_old[i][2] =
	    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 );
}
Пример #3
0
void Init_Forces_noQEq( reax_system *system, control_params *control,
                        simulation_data *data, storage *workspace,
                        reax_list **lists, output_controls *out_control,
                        MPI_Comm comm ) {
  int i, j, pj;
  int start_i, end_i;
  int type_i, type_j;
  int btop_i, btop_j, num_bonds, num_hbonds;
  int ihb, jhb, ihb_top, jhb_top;
  int local, flag, renbr;
  double cutoff;
  reax_list *far_nbrs, *bonds, *hbonds;
  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;
  bonds = *lists + BONDS;
  hbonds = *lists + HBONDS;

  for( i = 0; i < system->n; ++i )
    workspace->bond_mark[i] = 0;
  for( i = system->n; i < system->N; ++i ) {
    workspace->bond_mark[i] = 1000; // put ghost atoms to an infinite distance
  }

  num_bonds = 0;
  num_hbonds = 0;
  btop_i = btop_j = 0;
  renbr = (data->step-data->prev_steps) % control->reneighbor == 0;

  for( i = 0; i < system->N; ++i ) {
    atom_i = &(system->my_atoms[i]);
    type_i  = atom_i->type;
    if (type_i < 0) continue;
    start_i = Start_Index(i, far_nbrs);
    end_i   = End_Index(i, far_nbrs);
    btop_i = End_Index( i, bonds );
    sbp_i = &(system->reax_param.sbp[type_i]);

    if( i < system->n ) {
      local = 1;
      cutoff = MAX( control->hbond_cut, control->bond_cut );
    }
    else {
      local = 0;
      cutoff = control->bond_cut;
    }

    ihb = -1;
    ihb_top = -1;
    if( local && control->hbond_cut > 0 ) {
      ihb = sbp_i->p_hbond;
      if( ihb == 1 )
        ihb_top = End_Index( atom_i->Hindex, hbonds );
      else ihb_top = -1;
    }

    /* update i-j distance - check if j is within cutoff */
    for( pj = start_i; pj < end_i; ++pj ) {
      nbr_pj = &( far_nbrs->select.far_nbr_list[pj] );
      j = nbr_pj->nbr;
      atom_j = &(system->my_atoms[j]);

      if( renbr ) {
        if( nbr_pj->d <= cutoff )
          flag = 1;
        else flag = 0;
      }
      else{
        nbr_pj->dvec[0] = atom_j->x[0] - atom_i->x[0];
        nbr_pj->dvec[1] = atom_j->x[1] - atom_i->x[1];
        nbr_pj->dvec[2] = atom_j->x[2] - atom_i->x[2];
        nbr_pj->d = rvec_Norm_Sqr( nbr_pj->dvec );
        if( nbr_pj->d <= SQR(cutoff) ) {
          nbr_pj->d = sqrt(nbr_pj->d);
          flag = 1;
        }
        else {
          flag = 0;
        }
      }

      if( flag ) {
        type_j = atom_j->type;
	if (type_j < 0) continue;
        sbp_j = &(system->reax_param.sbp[type_j]);
        twbp = &(system->reax_param.tbp[type_i][type_j]);

        if( local ) {
          /* hydrogen bond lists */
          if( control->hbond_cut > 0 && (ihb==1 || ihb==2) &&
              nbr_pj->d <= control->hbond_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( j < system->n && ihb == 2 && jhb == 1 ) {
              jhb_top = End_Index( atom_j->Hindex, 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( atom_j->Hindex, jhb_top+1, hbonds );
              ++num_hbonds;
            }
          }
        }

        if( //(workspace->bond_mark[i] < 3 || workspace->bond_mark[j] < 3) &&
            nbr_pj->d <= control->bond_cut &&
            BOp( workspace, bonds, control->bo_cut,
                 i , btop_i, nbr_pj, sbp_i, sbp_j, twbp ) ) {
          num_bonds += 2;
          ++btop_i;

          if( workspace->bond_mark[j] > workspace->bond_mark[i] + 1 )
            workspace->bond_mark[j] = workspace->bond_mark[i] + 1;
          else if( workspace->bond_mark[i] > workspace->bond_mark[j] + 1 ) {
            workspace->bond_mark[i] = workspace->bond_mark[j] + 1;
          }
        }
      }
    }

    Set_End_Index( i, btop_i, bonds );
    if( local && ihb == 1 )
      Set_End_Index( atom_i->Hindex, ihb_top, hbonds );
  }


  workspace->realloc.num_bonds = num_bonds;
  workspace->realloc.num_hbonds = num_hbonds;

  Validate_Lists( system, workspace, lists, data->step,
                  system->n, system->N, system->numH, comm );
}
Пример #4
0
void Init_Forces( reax_system *system, control_params *control,
                  simulation_data *data, storage *workspace, reax_list **lists,
                  output_controls *out_control, MPI_Comm comm ) {
  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 local, flag, renbr;
  real r_ij, cutoff;
  sparse_matrix *H;
  reax_list *far_nbrs, *bonds, *hbonds;
  single_body_parameters *sbp_i, *sbp_j;
  two_body_parameters *twbp;
  far_neighbor_data *nbr_pj;
  reax_atom *atom_i, *atom_j;

  far_nbrs = *lists + FAR_NBRS;
  bonds = *lists + BONDS;
  hbonds = *lists + HBONDS;

  for( i = 0; i < system->n; ++i )
    workspace->bond_mark[i] = 0;
  for( i = system->n; i < system->N; ++i ) {
    workspace->bond_mark[i] = 1000; // put ghost atoms to an infinite distance
    //workspace->done_after[i] = Start_Index( i, far_nbrs );
  }

  H = workspace->H;
  H->n = system->n;
  Htop = 0;
  num_bonds = 0;
  num_hbonds = 0;
  btop_i = btop_j = 0;
  renbr = (data->step-data->prev_steps) % control->reneighbor == 0;

  for( i = 0; i < system->N; ++i ) {
    atom_i = &(system->my_atoms[i]);
    type_i  = atom_i->type;
    start_i = Start_Index(i, far_nbrs);
    end_i   = End_Index(i, far_nbrs);
    btop_i = End_Index( i, bonds );
    sbp_i = &(system->reax_param.sbp[type_i]);

    if( i < system->n ) {
      local = 1;
      cutoff = control->nonb_cut;
    }
    else {
      local = 0;
      cutoff = control->bond_cut;
    }

    ihb = -1;
    ihb_top = -1;
    if( local ) {
      H->start[i] = Htop;
      H->entries[Htop].j = i;
      H->entries[Htop].val = sbp_i->eta;
      ++Htop;

      if( control->hbond_cut > 0 ) {
        ihb = sbp_i->p_hbond;
        if( ihb == 1 )
          ihb_top = End_Index( atom_i->Hindex, hbonds );
        else ihb_top = -1;
      }
    }

    /* update i-j distance - check if j is within cutoff */
    for( pj = start_i; pj < end_i; ++pj ) {
      nbr_pj = &( far_nbrs->select.far_nbr_list[pj] );
      j = nbr_pj->nbr;
      atom_j = &(system->my_atoms[j]);
      //fprintf( stderr, "%d%d i=%d x_i: %f %f %f,j=%d x_j: %f %f %f, d=%f\n",
      //         MIN(atom_i->orig_id, atom_j->orig_id),
      //         MAX(atom_i->orig_id, atom_j->orig_id),
      //         i, atom_i->x[0], atom_i->x[1], atom_i->x[2],
      //         j, atom_j->x[0], atom_j->x[1], atom_j->x[2], nbr_pj->d );
      if( renbr ) {
        if(nbr_pj->d <= cutoff)
          flag = 1;
        else flag = 0;
      }
      else{
        nbr_pj->dvec[0] = atom_j->x[0] - atom_i->x[0];
        nbr_pj->dvec[1] = atom_j->x[1] - atom_i->x[1];
        nbr_pj->dvec[2] = atom_j->x[2] - atom_i->x[2];
        nbr_pj->d = rvec_Norm_Sqr( nbr_pj->dvec );
        if( nbr_pj->d <= SQR(cutoff) ) {
          nbr_pj->d = sqrt(nbr_pj->d);
          flag = 1;
        }
        else {
          flag = 0;
        }
      }

      if( flag ){
        type_j = atom_j->type;
        r_ij = nbr_pj->d;
        sbp_j = &(system->reax_param.sbp[type_j]);
        twbp = &(system->reax_param.tbp[type_i][type_j]);

        if( local ) {
          /* H matrix entry */
          if( j < system->n || atom_i->orig_id < atom_j->orig_id ) {//tryQEq||1
            H->entries[Htop].j = j;
            //fprintf( stdout, "%d%d %d %d\n",
            //     MIN(atom_i->orig_id, atom_j->orig_id),
            //     MAX(atom_i->orig_id, atom_j->orig_id),
            //     MIN(atom_i->orig_id, atom_j->orig_id),
            //     MAX(atom_i->orig_id, atom_j->orig_id) );
            if( control->tabulate == 0 )
              H->entries[Htop].val = Compute_H(r_ij,twbp->gamma,workspace->Tap);
            else H->entries[Htop].val = Compute_tabH(r_ij, type_i, type_j);
            ++Htop;
          }

          /* hydrogen bond lists */
          if( control->hbond_cut > 0 && (ihb==1 || ihb==2) &&
              nbr_pj->d <= control->hbond_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( j < system->n && ihb == 2 && jhb == 1 ) {
              jhb_top = End_Index( atom_j->Hindex, 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( atom_j->Hindex, jhb_top+1, hbonds );
              ++num_hbonds;
            }
          }
        }

        /* uncorrected bond orders */
        if( //(workspace->bond_mark[i] < 3 || workspace->bond_mark[j] < 3) &&
            nbr_pj->d <= control->bond_cut &&
            BOp( workspace, bonds, control->bo_cut,
                 i , btop_i, nbr_pj, sbp_i, sbp_j, twbp ) ) {
          num_bonds += 2;
          ++btop_i;

          if( workspace->bond_mark[j] > workspace->bond_mark[i] + 1 )
            workspace->bond_mark[j] = workspace->bond_mark[i] + 1;
          else if( workspace->bond_mark[i] > workspace->bond_mark[j] + 1 ) {
            workspace->bond_mark[i] = workspace->bond_mark[j] + 1;
            //if( workspace->bond_mark[i] == 1000 )
            //  workspace->done_after[i] = pj;
          }
          //fprintf( stdout, "%d%d - %d(%d) %d(%d)\n",
          //   i , j, i, workspace->bond_mark[i], j, workspace->bond_mark[j] );
        }
      }
    }

    Set_End_Index( i, btop_i, bonds );
    if( local ) {
      H->end[i] = Htop;
      if( ihb == 1 )
        Set_End_Index( atom_i->Hindex, ihb_top, hbonds );
    }
  }

  //fprintf( stderr, "after the first init loop\n" );
  /*for( i = system->n; i < system->N; ++i )
    if( workspace->bond_mark[i] > 3 ) {
      start_i = Start_Index(i, bonds);
      end_i = End_Index(i, bonds);
      num_bonds -= (end_i - start_i);
      Set_End_Index(i, start_i, bonds );
      }*/

  /*for( i = system->n; i < system->N; ++i ) {
    start_i = Start_Index(i, far_nbrs);
    end_i = workspace->done_after[i];

    if( workspace->bond_mark[i] >= 2 && start_i < end_i ) {
      atom_i = &(system->my_atoms[i]);
      type_i = atom_i->type;
      btop_i = End_Index( i, bonds );
      sbp_i = &(system->reax_param.sbp[type_i]);

      for( pj = start_i; pj < end_i; ++pj ) {
        nbr_pj = &( far_nbrs->select.far_nbr_list[pj] );
        j = nbr_pj->nbr;

        if( workspace->bond_mark[j] >= 2 && nbr_pj->d <= control->bond_cut ) {
          atom_j = &(system->my_atoms[j]);
          type_j = atom_j->type;
          sbp_j = &(system->reax_param.sbp[type_j]);
          twbp = &(system->reax_param.tbp[type_i][type_j]);

          if( BOp( workspace, bonds, control->bo_cut,
                   i , btop_i, nbr_pj, sbp_i, sbp_j, twbp ) ) {
            num_bonds += 2;
            ++btop_i;

            if( workspace->bond_mark[j] > workspace->bond_mark[i] + 1 )
              workspace->bond_mark[j] = workspace->bond_mark[i] + 1;
            else if( workspace->bond_mark[i] > workspace->bond_mark[j] + 1 )
              workspace->bond_mark[i] = workspace->bond_mark[j] + 1;

            //fprintf( stdout, "%d%d - %d(%d) %d(%d) new\n",
            // i , j, i, workspace->bond_mark[i], j, workspace->bond_mark[j] );
          }
        }
      }
      Set_End_Index( i, btop_i, bonds );
    }
    }*/

  workspace->realloc.Htop = Htop;
  workspace->realloc.num_bonds = num_bonds;
  workspace->realloc.num_hbonds = num_hbonds;

#if defined(DEBUG_FOCUS)
  fprintf( stderr, "p%d @ step%d: Htop = %d num_bonds = %d num_hbonds = %d\n",
           system->my_rank, data->step, Htop, num_bonds, num_hbonds );
  MPI_Barrier( comm );
#endif
#if defined( DEBUG )
  Print_Bonds( system, bonds, "debugbonds.out" );
  Print_Bond_List2( system, bonds, "pbonds.out" );
  Print_Sparse_Matrix( system, H );
  for( i = 0; i < H->n; ++i )
    for( j = H->start[i]; j < H->end[i]; ++j )
      fprintf( stderr, "%d %d %.15e\n",
               MIN(system->my_atoms[i].orig_id,
                   system->my_atoms[H->entries[j].j].orig_id),
               MAX(system->my_atoms[i].orig_id,
                   system->my_atoms[H->entries[j].j].orig_id),
               H->entries[j].val );
#endif

  Validate_Lists( system, workspace, lists, data->step,
                  system->n, system->N, system->numH, comm );
}
Пример #5
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 );

}