示例#1
0
Analysis::RetType Analysis_Integrate::Analyze() {
  double sum;
  int idx = 0;
  for (Array1D::const_iterator DS = input_dsets_.begin();
                               DS != input_dsets_.end(); ++DS, ++idx)
  {
    if ( (*DS)->Size() < 1)
      mprintf("Warning: Set [%i] \"%s\" has no data.\n", idx, (*DS)->legend());
    else {
      DataSet_Mesh mesh;
      // Set XY mesh
      mesh.SetMeshXY( *(*DS) );
      if (outfile_ != 0)
        sum = mesh.Integrate_Trapezoid( *(output_dsets_[idx]) );
      else
        sum = mesh.Integrate_Trapezoid();
      mprintf("\tIntegral of %s is %g\n", (*DS)->legend(), sum);
    }
  }
  return Analysis::OK;
}
示例#2
0
// Action_VelocityAutoCorr::Print()
void Action_VelocityAutoCorr::Print() {
  if (Vel_.empty()) return;
  mprintf("    VELOCITYAUTOCORR:\n");
  mprintf("\t%zu vectors have been saved, total length of each = %zu\n",
          Vel_.size(), Vel_[0].Size());
  int maxlag;
  if (maxLag_ <= 0) {
    maxlag = (int)Vel_[0].Size() / 2;
    mprintf("\tSetting maximum lag to 1/2 total time (%i)\n", maxlag);
  } else if (maxLag_ > (int)Vel_[0].Size()) {
    maxlag = (int)Vel_[0].Size();
    mprintf("\tSpecified maximum lag > total length, setting to %i\n", maxlag);
  } else
    maxlag = maxLag_;
  // DEBUG
  //for (VelArray::iterator vel = Vel_.begin(); vel != Vel_.end(); ++vel) {
  //  mprintf("Vector %u:\n", vel - Vel_.begin());
  //  for (DataSet_Vector::iterator vec = vel->begin(); vec != vel->end(); ++vec)
  //    mprintf("\t%u {%f %f %f}\n", vec - vel->begin(), (*vec)[0], (*vec)[1], (*vec)[2]);
  //}
  // Allocate space for output correlation function values.
  DataSet_double& Ct = static_cast<DataSet_double&>( *VAC_ );
  Ct.Resize( maxlag );
  if (!useFFT_) {
    // DIRECT METHOD 
    ParallelProgress progress( maxlag );
    int t;
    unsigned int dtmax, dt;
#   ifdef _OPENMP
#   pragma omp parallel private(t, dtmax, dt) firstprivate(progress)
    {
      progress.SetThread(omp_get_thread_num());
#     pragma omp for schedule(dynamic)
#   endif
      for (t = 0; t < maxlag; ++t)
      {
        progress.Update( t );
        dtmax = Vel_[0].Size() - t;
        for (dt = 0; dt < dtmax; ++dt)
        {
          for (VelArray::const_iterator vel = Vel_.begin(); vel != Vel_.end(); ++vel)
            Ct[t] += (*vel)[dt] * (*vel)[dt + t];
        }
        Ct[t] /= (double)(dtmax * Vel_.size());
        //mprintf("\tCt[%i]= %f\n", t, Ct[t]); // DEBUG
      }
#   ifdef _OPENMP
    } // END pragma omp parallel
#   endif
    progress.Finish();
  } else {
    // FFT METHOD
    // Since FFT is cyclic, unroll vectors into a 1D array; in the resulting
    // transformed array after FFT, every 3rd value will be the correlation
    // via dot products that we want (once it is normalized).
    unsigned int total_length = Vel_[0].Size() * 3;
    CorrF_FFT pubfft;
    pubfft.CorrSetup( total_length );
    ComplexArray data1 = pubfft.Array();
    //mprintf("Complex Array Size is %i (%i actual)\n", data1.size(), data1.size()*2);
    ProgressBar progress( Vel_.size() );
    unsigned int nvel = 0;
    for (VelArray::iterator vel = Vel_.begin(); vel != Vel_.end(); ++vel, ++nvel)
    {
      //mprintf("Vector %u\n", vel - Vel_.begin()); // DEBUG
      progress.Update( nvel );
      // Place vector from each frame into 1D array
      unsigned int nd = 0; // Will be used to index complex data
      for (DataSet_Vector::const_iterator vec = vel->begin(); vec != vel->end(); ++vec, nd+=6)
      {
        //mprintf("\tFrame %u assigned to complex array %u\n", vec - vel->begin(), nd); // DEBUG
        data1[nd  ] = (*vec)[0]; data1[nd+1] = 0.0;
        data1[nd+2] = (*vec)[1]; data1[nd+3] = 0.0;
        data1[nd+4] = (*vec)[2]; data1[nd+5] = 0.0;
        //mprintf("\t  Complex[%u]= %f  Complex[%u]= %f  Complex[%u]= %f\n", // DEBUG
        //        nd, data1[nd], nd+2, data1[nd+2], nd+4, data1[nd+4]);
      }
      data1.PadWithZero( total_length );
      //mprintf("Before FFT:\n"); // DEBUG
      //for (unsigned int cd = 0; cd < (unsigned int)data1.size()*2; cd += 2)
      //  mprintf("\t%u: %f + %fi\n", cd/2, data1[cd], data1[cd+1]);
      pubfft.AutoCorr( data1 );
      //mprintf("Results of FFT:\n"); // DEBUG
      //for (unsigned int cd = 0; cd < (unsigned int)data1.size()*2; cd += 2)
      //  mprintf("\t%u: %f + %fi\n", cd/2, data1[cd], data1[cd+1]);
      // Increment nd by 3 here so it can be used for normalization.
      nd = 0;
      for (int t = 0; t < maxlag; t++, nd += 3) {
        //mprintf("\tdata1[%u] = %f", nd*2, data1[nd*2]); // DEBUG
        //mprintf("  norm= %u", total_length - nd); // DEBUG
        //Ct[t] += data1[nd*2] * 3.0 / (double)(total_length - nd);
        Ct[t] += data1[nd*2];
        //mprintf("  Ct[%i]= %f\n", t, Ct[t]); // DEBUG
      }
    }
    // Normalization
    for (int t = 0, nd = 0; t < maxlag; t++, nd += 3)
      Ct[t] *= ( 3.0 / (double)((total_length - nd) * Vel_.size()) );
      //Ct[t] /= (double)Vel_.size();
  }
  // Integration to get diffusion coefficient.
  VAC_->SetDim(Dimension::X, Dimension(1.0, tstep_, "Frame"));
  mprintf("\tIntegrating data set %s, step is %f\n", VAC_->legend(), VAC_->Dim(0).Step());
  DataSet_Mesh mesh;
  mesh.SetMeshXY( static_cast<DataSet_1D const&>(*VAC_) );
  double total = mesh.Integrate_Trapezoid();
  const double ANG2_PS_TO_CM2_S = 10.0 / 6.0;
  mprintf("\t3D= %g Å^2/ps, %g x10^-5 cm^2/s\n", total, total * ANG2_PS_TO_CM2_S);
  mprintf("\t D= %g Å^2/ps, %g x10^-5 cm^2/s\n", total / 3.0, total * ANG2_PS_TO_CM2_S / 3.0);
  mprintf("\t6D= %g Å^2/ps, %g x10^-5 cm^2/s\n", total * 2.0, total * ANG2_PS_TO_CM2_S * 2.0);
  if (normalize_) {
    // Normalize VAC fn to 1.0
    mprintf("\tNormalizing VAC function to 1.0, C[0]= %g\n", Ct[0]);
    double norm = 1.0 / Ct[0];
    for (int t = 0; t < maxlag; ++t)
      Ct[t] *= norm;
  }
}