void Wf_return::mpiSend(int node) {
#ifdef USE_MPI
  int nwf, nst;
  nwf=amp.GetDim(0); nst=amp.GetDim(1);
  MPI_Send(&nwf, 1, MPI_INT, node, 0, MPI_Comm_grp);
  MPI_Send(&nst, 1, MPI_INT, node, 0, MPI_Comm_grp);
  MPI_Send(&is_complex, 1, MPI_INT, node, 0, MPI_Comm_grp);
  
  MPI_Send(amp.v, nwf*nst, MPI_DOUBLE, node, 0, MPI_Comm_grp);
  MPI_Send(phase.v, nwf*nst, MPI_DOUBLE, node, 0, MPI_Comm_grp);
  
  if(is_complex) {
    for(int w=0; w < nwf; w++) {
      for(int i=0; i < nst; i++) {
        doublevar tmp=cvals(w,i).real();
        MPI_Send(&tmp, 1, MPI_DOUBLE, node, 0, MPI_Comm_grp);
        tmp=cvals(w,i).imag();
        MPI_Send(&tmp, 1, MPI_DOUBLE, node, 0, MPI_Comm_grp);
      }
    }
  }
  
#endif
  
}
Beispiel #2
0
void fftRealInplace(std::vector<_REAL>& vals1,
                    std::vector<_REAL>& vals2, int dir)
{
  assert(dir == 1 || dir == -1);
  assert(vals1.size() == vals2.size());

  int n = vals1.size();
  std::vector<std::complex<_REAL> > cvals(n);

  // convert the two real sequences into one convex sequence
  for (int i = 0; i < n; ++i)
    {
      std::complex<_REAL> t(vals1[i],vals2[i]);
      cvals[i] = t;
    }
  
  fftInplace(cvals,dir);

  // convert the std::complex dft-sequence cvals into the two real
  // dft-sequences vals1 and vals2
  for (int i = 0; i < n; ++i)
    {
      vals1[i] = (cvals[i] + conj(cvals[n-i])).real() / 2.0;
      vals2[i] 
	= (std::complex<_REAL>(0,-1)*(cvals[i] - conj(cvals[n-i]))).real()/2;
    }
}
Beispiel #3
0
void fftRealRecursive(const std::vector<_REAL>& vals1,
			   const std::vector<_REAL>& vals2,
			   std::vector<_REAL>& rvals1,
			   std::vector<_REAL>& rvals2, int dir)
{
  assert(vals1.size() == vals2.size());
  assert(vals2.size() == rvals1.size());
  assert(rvals1.size() == rvals2.size());

  int N = vals1.size();
  std::vector<std::complex<_REAL> > cvals(N);
  std::vector<std::complex<_REAL> > rcvals(N);

  // convert the two real sequences into one convex sequence
  for (int i = 0; i < N; ++i)
    {
      cvals[i] = std::complex<_REAL>(vals1[i], vals2[i]);
    }
  
  fftRecursive(cvals,rcvals,dir);

  // convert the std::complex dft-sequence rcvals into the two real
  // dft-sequences rvals1 and rvals2
  for (int i = 0; i < N; ++i)
    {
      rvals1[i] = (rcvals[i] + conj(rcvals[N-i])).real() / 2.0;
      rvals2[i] 
	= (std::complex<_REAL>(0,-1)*(rcvals[i] - conj(rcvals[N-i]))).real()/2.0;
    }
}
void Wf_return::mpiRecieve(int node) {
#ifdef USE_MPI
  int nwf, nst;
  MPI_Status status;
  
  MPI_Recv(&nwf, 1, MPI_INT, node, 0, MPI_Comm_grp, &status);
  MPI_Recv(&nst, 1, MPI_INT, node, 0, MPI_Comm_grp, &status);
  MPI_Recv(&is_complex, 1, MPI_INT, node, 0, MPI_Comm_grp, &status);
  
  Resize(nwf, nst);
  MPI_Recv(amp.v, nwf*nst, MPI_DOUBLE, node, 0, MPI_Comm_grp, & status);
  MPI_Recv(phase.v, nwf*nst, MPI_DOUBLE, node, 0, MPI_Comm_grp, &status);
  if(is_complex) {
    for(int w=0; w < nwf; w++) {
      for(int i=0; i < nst; i++) {
        doublevar tmp1, tmp2;
        MPI_Recv(&tmp1, 1, MPI_DOUBLE, node, 0, MPI_Comm_grp, &status);
        MPI_Recv(&tmp2, 1, MPI_DOUBLE, node, 0, MPI_Comm_grp, &status);
        cvals(w,i)=dcomplex(tmp1, tmp2);
      }
    }
  }  
  
#endif
}
double DistanceFromContour::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
  Vector distance = getSeparation( getPosition(getNumberOfAtoms()-1), myatoms.getPosition(0) );
  std::vector<double> pp(3), der(3,0); for(unsigned j=0;j<3;++j) pp[j] = distance[j]; 

  // Now create the kernel and evaluate
  KernelFunctions kernel( pp, bw, kerneltype, false, 1.0, true );
  double newval = kernel.evaluate( pval, der, true );

  if( mybasemulticolvars[0]->isDensity() ){ 
      if( !doNotCalculateDerivatives() && derivTime ){
          MultiValue& myvals=myatoms.getUnderlyingMultiValue();
          Vector vder; unsigned basen=myvals.getNumberOfDerivatives() - 12;
          for(unsigned i=0;i<3;++i){ 
              vder[i]=der[i]; myvals.addDerivative( 1, basen+i, vder[i] ); 
          }
          myatoms.setValue( 2, der[dir] );
          addAtomDerivatives( 1, 0, -vder, myatoms );
          myatoms.addBoxDerivatives( 1, Tensor(vder,distance) );
      }
      myatoms.setValue( 0, 1.0 ); return newval; 
  }

  // This does the stuff for averaging
  myatoms.setValue( 0, newval );

  // This gets the average if we are using a phase field
  std::vector<double> cvals( mybasemulticolvars[0]->getNumberOfQuantities() );
  mybasedata[0]->retrieveValueWithIndex( tindex, false, cvals );
  return newval*cvals[0]*cvals[1]; 
}
void Wf_return::setVals(Array2 <doublevar> & vals, Array1 <doublevar> & sign) {
  is_complex=0;
  for(int w=0; w< vals.GetDim(0); w++) {
    for(int i=0; i< vals.GetDim(1); i++) {
      cvals(w,i)=vals(w,i);
    }
  }
  amp=vals;
  
  phase=0;
  
  for(int w=0; w< sign.GetDim(0); w++) {
    phase(w,0)=.5*pi*(1-sign(w));
  }
  
}
Beispiel #7
0
void Histogram::prepareForAveraging() {
  if( myvessels.size()>0 ) {
    deactivateAllTasks(); double norm=0;
    for(unsigned i=0; i<stashes[0]->getNumberOfStoredValues(); ++i) {
      std::vector<double> cvals( myvessels[0]->getNumberOfQuantities() );
      stashes[0]->retrieveSequentialValue( i, false, cvals );
      unsigned itask=myvessels[0]->getActiveTask(i); double tnorm = cvals[0];
      for(unsigned j=1; j<myvessels.size(); ++j) {
        if( myvessels[j]->getActiveTask(i)!=itask ) error("mismatched task identities in histogram suggests histogram is meaningless");
        if( cvals.size()!=myvessels[j]->getNumberOfQuantities() ) cvals.resize( myvessels[j]->getNumberOfQuantities() );
        stashes[j]->retrieveSequentialValue( i, false, cvals ); tnorm *= cvals[0];
      }
      norm += tnorm; taskFlags[i]=1;
    }
    lockContributors();
    // Sort out normalization of histogram
    if( !noNormalization() ) ww = cweight / norm;
    else ww = cweight;
  } else {
    // Now fetch the kernel and the active points
    std::vector<double> point( getNumberOfArguments() );
    for(unsigned i=0; i<point.size(); ++i) point[i]=getArgument(i);
    unsigned num_neigh; std::vector<unsigned> neighbors(1);
    kernel = myhist->getKernelAndNeighbors( point, num_neigh, neighbors );

    if( num_neigh>1 ) {
      // Activate relevant tasks
      deactivateAllTasks();
      for(unsigned i=0; i<num_neigh; ++i) taskFlags[neighbors[i]]=1;
      lockContributors();
    } else {
      // This is used when we are not doing kernel density evaluation
      mygrid->addToGridElement( neighbors[0], 0, cweight );
    }
  }
}
Beispiel #8
0
void Histogram::compute( const unsigned& current, MultiValue& myvals ) const {
  if( mvectors ) {
    std::vector<double> cvals( myvessels[0]->getNumberOfQuantities() );
    stashes[0]->retrieveSequentialValue( current, true, cvals );
    for(unsigned i=2; i<myvessels[0]->getNumberOfQuantities(); ++i) myvals.setValue( i-1, cvals[i] );
    myvals.setValue( 0, cvals[0] ); myvals.setValue( myvessels[0]->getNumberOfQuantities() - 1, ww );
    if( in_apply ) {
      MultiValue& tmpval = stashes[0]->getTemporyMultiValue(0);
      if( tmpval.getNumberOfValues()!=myvessels[0]->getNumberOfQuantities() ||
          tmpval.getNumberOfDerivatives()!=myvessels[0]->getNumberOfDerivatives() )
        tmpval.resize( myvessels[0]->getNumberOfQuantities(), myvessels[0]->getNumberOfDerivatives() );
      stashes[0]->retrieveDerivatives( stashes[0]->getTrueIndex(current), true, tmpval );
      for(unsigned j=0; j<tmpval.getNumberActive(); ++j) {
        unsigned jder=tmpval.getActiveIndex(j); myvals.addDerivative( 0, jder, tmpval.getDerivative(0, jder) );
        for(unsigned i=2; i<myvessels[0]->getNumberOfQuantities(); ++i) myvals.addDerivative( i-1, jder, tmpval.getDerivative(i, jder) );
      }
      myvals.updateDynamicList();
    }
  } else if( myvessels.size()>0 ) {
    std::vector<double> cvals( myvessels[0]->getNumberOfQuantities() );
    stashes[0]->retrieveSequentialValue( current, false, cvals );
    unsigned derbase; double totweight=cvals[0], tnorm = cvals[0]; myvals.setValue( 1, cvals[1] );
    // Get the derivatives as well if we are in apply
    if( in_apply ) {
      // This bit gets the total weight
      double weight0 = cvals[0];  // Store the current weight
      for(unsigned j=1; j<myvessels.size(); ++j) {
        stashes[j]->retrieveSequentialValue( current, false, cvals ); totweight *= cvals[0];
      }
      // And this bit the derivatives
      MultiValue& tmpval = stashes[0]->getTemporyMultiValue(0);
      if( tmpval.getNumberOfValues()!=myvessels[0]->getNumberOfQuantities() ||
          tmpval.getNumberOfDerivatives()!=myvessels[0]->getNumberOfDerivatives() )
        tmpval.resize( myvessels[0]->getNumberOfQuantities(), myvessels[0]->getNumberOfDerivatives() );
      stashes[0]->retrieveDerivatives( stashes[0]->getTrueIndex(current), false, tmpval );
      for(unsigned j=0; j<tmpval.getNumberActive(); ++j) {
        unsigned jder=tmpval.getActiveIndex(j);
        myvals.addDerivative( 1, jder, tmpval.getDerivative(1,jder) );
        myvals.addDerivative( 0, jder, (totweight/weight0)*tmpval.getDerivative(0,jder) );
      }
      derbase = myvessels[0]->getNumberOfDerivatives();
    }
    for(unsigned i=1; i<myvessels.size(); ++i) {
      if( cvals.size()!=myvessels[i]->getNumberOfQuantities() ) cvals.resize( myvessels[i]->getNumberOfQuantities() );
      stashes[i]->retrieveSequentialValue( current, false, cvals );
      tnorm *= cvals[0]; myvals.setValue( 1+i, cvals[1] );
      // Get the derivatives as well if we are in apply
      if( in_apply ) {
        MultiValue& tmpval = stashes[0]->getTemporyMultiValue(0);
        if( tmpval.getNumberOfValues()!=myvessels[0]->getNumberOfQuantities() ||
            tmpval.getNumberOfDerivatives()!=myvessels[0]->getNumberOfDerivatives() )
          tmpval.resize( myvessels[0]->getNumberOfQuantities(), myvessels[0]->getNumberOfDerivatives() );
        stashes[i]->retrieveDerivatives( stashes[i]->getTrueIndex(current), false, tmpval );
        for(unsigned j=0; j<tmpval.getNumberActive(); ++j) {
          unsigned jder=tmpval.getActiveIndex(j);
          myvals.addDerivative( 1+i, derbase+jder, tmpval.getDerivative(1,jder) );
          myvals.addDerivative( 0, derbase+jder, (totweight/cvals[0])*tmpval.getDerivative(0,jder) );
        }
        derbase += myvessels[i]->getNumberOfDerivatives();
      }
    }
    myvals.setValue( 0, tnorm ); myvals.setValue( 1+myvessels.size(), ww );
    if( in_apply ) myvals.updateDynamicList();
  } else {
    plumed_assert( !in_apply );
    std::vector<Value*> vv( myhist->getVectorOfValues() );
    std::vector<double> val( getNumberOfArguments() ), der( getNumberOfArguments() );
    // Retrieve the location of the grid point at which we are evaluating the kernel
    mygrid->getGridPointCoordinates( current, val );
    if( kernel ) {
      for(unsigned i=0; i<getNumberOfArguments(); ++i) vv[i]->set( val[i] );
      // Evaluate the histogram at the relevant grid point and set the values
      double vvh = kernel->evaluate( vv, der,true); myvals.setValue( 1, vvh );
    } else {
      plumed_merror("normalisation of vectors does not work with arguments and spherical grids");
      // Evalulate dot product
      double dot=0; for(unsigned j=0; j<getNumberOfArguments(); ++j) { dot+=val[j]*getArgument(j); der[j]=val[j]; }
      // Von misses distribution for concentration parameter
      double newval = (myhist->von_misses_norm)*exp( (myhist->von_misses_concentration)*dot ); myvals.setValue( 1, newval );
      // And final derivatives
      for(unsigned j=0; j<getNumberOfArguments(); ++j) der[j] *= (myhist->von_misses_concentration)*newval;
    }
    // Set the derivatives and delete the vector of values
    for(unsigned i=0; i<getNumberOfArguments(); ++i) { myvals.setDerivative( 1, i, der[i] ); delete vv[i]; }
  }
}