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 }
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; } }
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)); } }
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 ); } } }
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]; } } }