void SecondaryStructureRMSD::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
  // Retrieve the positions
  std::vector<Vector> pos( references[0]->getNumberOfAtoms() );
  const unsigned n=pos.size();
  for(unsigned i=0;i<n;++i) pos[i]=ActionAtomistic::getPosition( getAtomIndex(current,i) );

  // This does strands cutoff
  Vector distance=pbcDistance( pos[align_atom_1],pos[align_atom_2] ); 
  if( s_cutoff2>0 ){
     if( distance.modulo2()>s_cutoff2 ){
       myvals.setValue( 0, 0.0 );
       return;
     }
  }

  // This aligns the two strands if this is required
  if( alignType!="DRMSD" && align_strands ){
     Vector origin_old, origin_new; origin_old=pos[align_atom_2];
     origin_new=pos[align_atom_1]+distance;
     for(unsigned i=15;i<30;++i){
         pos[i]+=( origin_new - origin_old );
     }
  }
  // Create a holder for the derivatives
  ReferenceValuePack mypack( 0, pos.size(), myvals ); mypack.setValIndex( 1 );
  for(unsigned i=0;i<n;++i) mypack.setAtomIndex( i, getAtomIndex(current,i) );

  // And now calculate the RMSD
  const Pbc& pbc=getPbc(); 
  unsigned closest=0; 
  double r = references[0]->calculate( pos, pbc, mypack, false );
  const unsigned rs = references.size();
  for(unsigned i=1;i<rs;++i){
    mypack.setValIndex( i+1 );
    double nr=references[i]->calculate( pos, pbc, mypack, false );
    if( nr<r ){ closest=i; r=nr; }
  }

  // Transfer everything to the value
  myvals.setValue( 0, 1.0 ); myvals.setValue( 1, r );
  if( closest>0 ) mypack.moveDerivatives( closest+1, 1 );

  if( !mypack.virialWasSet() ){
    Tensor vir;
    const unsigned cacs = colvar_atoms[current].size();
    for(unsigned i=0;i<cacs;++i){
       vir+=(-1.0*Tensor( pos[i], mypack.getAtomDerivative(i) ));
    } 
    mypack.setValIndex(1); mypack.addBoxDerivatives( vir );
  }

  return;
}
Пример #2
0
double DRMSD::calc( const std::vector<Vector>& pos, const Pbc& pbc, ReferenceValuePack& myder, const bool& squared ) const {
  plumed_dbg_assert(!targets.empty());

  Vector distance; 
  myder.clear(); 
  double drmsd=0.; 
  for(std::map< std::pair <unsigned,unsigned> , double>::const_iterator it=targets.begin();it!=targets.end();++it){
      
      const unsigned i=getAtomIndex( it->first.first );
      const unsigned j=getAtomIndex( it->first.second );

      if(nopbc) distance=delta( pos[i] , pos[j] ); 
      else      distance=pbc.distance( pos[i] , pos[j] );

      const double len = distance.modulo();
      const double diff = len - it->second;
      const double der = diff / len; 

      drmsd += diff * diff;
      myder.addAtomDerivatives( i, -der * distance );
      myder.addAtomDerivatives( j,  der * distance );
      myder.addBoxDerivatives( - der * Tensor(distance,distance) );
  }

  const double inpairs = 1./static_cast<double>(targets.size());
  double idrmsd;

  if(squared){
     drmsd = drmsd * inpairs;
     idrmsd = 2.0 * inpairs;
  } else {
     drmsd = sqrt( drmsd * inpairs );
     idrmsd = inpairs / drmsd ;
  }

  myder.scaleAllDerivatives( idrmsd );

  return drmsd;
}
Пример #3
0
double DRMSD::calc( const std::vector<Vector>& pos, const Pbc& pbc, const bool& squared ){
  plumed_dbg_assert( !targets.empty() );

  Vector distance; 
  double drmsd=0.; 
  for(std::map< std::pair <unsigned,unsigned> , double>::const_iterator it=targets.begin();it!=targets.end();++it){
      
      unsigned i=getAtomIndex( it->first.first );
      unsigned j=getAtomIndex( it->first.second );

      if(nopbc){ distance=delta( pos[i] , pos[j] ); }
      else{ distance=pbc.distance( pos[i] , pos[j] ); }

      double len = distance.modulo();
      double diff = len - it->second;

      drmsd += diff * diff;
      addAtomicDerivatives( i, -( diff / len ) * distance );
      addAtomicDerivatives( j, ( diff / len ) * distance );
      addBoxDerivatives( -( diff / len ) * Tensor(distance,distance) );
  }

  double npairs = static_cast<double>(targets.size());
  double idrmsd;

  if(squared){
     drmsd = drmsd / npairs;
     idrmsd = 2.0 / npairs;
  } else {
     drmsd = sqrt( drmsd / npairs );
     idrmsd = 1.0/( drmsd * npairs );
  }

  virial *= idrmsd; 
  for(unsigned i=0;i<getNumberOfAtoms();++i){atom_ders[i] *= idrmsd;}

  return drmsd;
}
Пример #4
0
void Steinhardt::calculateVector(){
  double dfunc, dpoly_ass, md, tq6, itq6, real_z, imag_z; 
  Vector distance, dz, myrealvec, myimagvec, real_dz, imag_dz;
  // The square root of -1
  std::complex<double> ii( 0.0, 1.0 ), dp_x, dp_y, dp_z;

  double sw, poly_ass, dlen, nbond=0.0; std::complex<double> powered;
  for(unsigned i=1;i<getNAtoms();++i){
     distance=getSeparation( getPosition(0), getPosition(i) );
     dlen=distance.modulo(); sw = switchingFunction.calculate( dlen, dfunc );
     if( sw>=getTolerance() ){   
         nbond += sw;  // Accumulate total number of bonds
         double dlen3 = dlen*dlen*dlen;

         // Store derivatives of weight
         MultiColvarBase::addAtomsDerivatives( 0, getAtomIndex(0), (-dfunc)*distance );
         MultiColvarBase::addAtomsDerivatives( 0, getAtomIndex(i), (+dfunc)*distance );
         MultiColvarBase::addBoxDerivatives( 0, (-dfunc)*Tensor( distance,distance ) ); 

         // Do stuff for m=0
         poly_ass=deriv_poly( 0, distance[2]/dlen, dpoly_ass );
         // Derivatives of z/r wrt x, y, z
         dz = -( distance[2] / dlen3 )*distance; dz[2] += (1.0 / dlen);
         // Derivative wrt to the vector connecting the two atoms
         myrealvec = (+sw)*dpoly_ass*dz + poly_ass*(+dfunc)*distance;
         // Accumulate the derivatives
         addAtomsDerivative( tmom, 0, -myrealvec );      
         addAtomsDerivative( tmom, i, myrealvec ); 
         addBoxDerivatives( tmom, Tensor( -myrealvec,distance ) );
         // And store the vector function
         addComponent( tmom, sw*poly_ass );

         // The complex number of which we have to take powers
         std::complex<double> com1( distance[0]/dlen ,distance[1]/dlen );

         // Do stuff for all other m values
         for(unsigned m=1;m<=tmom;++m){
             // Calculate Legendre Polynomial
             poly_ass=deriv_poly( m, distance[2]/dlen, dpoly_ass );
             // Calculate powe of complex number
             powered=pow(com1,m-1); md=static_cast<double>(m);
             // Real and imaginary parts of z
             real_z = real(com1*powered); imag_z = imag(com1*powered );
 
             // Calculate steinhardt parameter
             tq6=poly_ass*real_z;   // Real part of steinhardt parameter
             itq6=poly_ass*imag_z;  // Imaginary part of steinhardt parameter

             // Derivatives wrt ( x/r + iy )^m
             dp_x = md*powered*( (1.0/dlen)-(distance[0]*distance[0])/dlen3-ii*(distance[0]*distance[1])/dlen3 );
             dp_y = md*powered*( ii*(1.0/dlen)-(distance[0]*distance[1])/dlen3-ii*(distance[1]*distance[1])/dlen3 );
             dp_z = md*powered*( -(distance[0]*distance[2])/dlen3-ii*(distance[1]*distance[2])/dlen3 );

             // Derivatives of real and imaginary parts of above
             real_dz[0] = real( dp_x ); real_dz[1] = real( dp_y ); real_dz[2] = real( dp_z );
             imag_dz[0] = imag( dp_x ); imag_dz[1] = imag( dp_y ); imag_dz[2] = imag( dp_z );  

             // Complete derivative of steinhardt parameter
             myrealvec = (+sw)*dpoly_ass*real_z*dz + (+dfunc)*distance*tq6 + (+sw)*poly_ass*real_dz; 
             myimagvec = (+sw)*dpoly_ass*imag_z*dz + (+dfunc)*distance*itq6 + (+sw)*poly_ass*imag_dz;

             // Real part
             addComponent( tmom+m, sw*tq6 );
             addAtomsDerivative( tmom+m, 0, -myrealvec );
             addAtomsDerivative( tmom+m, i, myrealvec );
             addBoxDerivatives( tmom+m, Tensor( -myrealvec,distance ) );
             // Imaginary part 
             addImaginaryComponent( tmom+m, sw*itq6 );
             addImaginaryAtomsDerivative( tmom+m, 0, -myimagvec );
             addImaginaryAtomsDerivative( tmom+m, i, myimagvec );
             addImaginaryBoxDerivatives( tmom+m, Tensor( -myimagvec,distance ) );
             // Store -m part of vector
             double pref=pow(-1.0,m); 
             // -m part of vector is just +m part multiplied by (-1.0)**m and multiplied by complex
             // conjugate of Legendre polynomial
             // Real part
             addComponent( tmom-m, pref*sw*tq6 );
             addAtomsDerivative( tmom-m, 0, -pref*myrealvec );
             addAtomsDerivative( tmom-m, i, pref*myrealvec );
             addBoxDerivatives( tmom-m, pref*Tensor( -myrealvec,distance ) );
             // Imaginary part
             addImaginaryComponent( tmom-m, -pref*sw*itq6 );
             addImaginaryAtomsDerivative( tmom-m, 0, pref*myimagvec );
             addImaginaryAtomsDerivative( tmom-m, i, -pref*myimagvec );
             addImaginaryBoxDerivatives( tmom-m, pref*Tensor( myimagvec,distance ) );
         }
     } else {
         removeAtomRequest( i, sw );
     }
  } 

  // Normalize 
  setElementValue(0, nbond ); updateActiveAtoms();
  for(unsigned i=0;i<2*getNumberOfComponentsInVector();++i) quotientRule( 5+i, 0, 5+i ); 
  // Clear tempory stuff
  clearDerivativesAfterTask(0);
}
Пример #5
0
str
malAtomProperty(MalBlkPtr mb, InstrPtr pci)
{
	str name;
	int tpe;
	(void)mb;  /* fool compilers */
	assert(pci != 0);
	name = getFunctionId(pci);
	tpe = getAtomIndex(getModuleId(pci), (int)strlen(getModuleId(pci)), TYPE_any);
	if (tpe < 0 || tpe >= GDKatomcnt || tpe >= MAXATOMS)
		return MAL_SUCCEED;
	assert(pci->fcn != NULL);
	switch (name[0]) {
	case 'd':
		if (idcmp("del", name) == 0 && pci->argc == 1) {
			BATatoms[tpe].atomDel = (void (*)(Heap *, var_t *))pci->fcn;
			setAtomName(pci);
			return MAL_SUCCEED;
		}
		break;
	case 'c':
		if (idcmp("cmp", name) == 0 && pci->argc == 1) {
			BATatoms[tpe].atomCmp = (int (*)(const void *, const void *))pci->fcn;
			BATatoms[tpe].linear = true;
			setAtomName(pci);
			return MAL_SUCCEED;
		}
		break;
	case 'f':
		if (idcmp("fromstr", name) == 0 && pci->argc == 1) {
			BATatoms[tpe].atomFromStr = (ssize_t (*)(const char *, size_t *, ptr *, bool))pci->fcn;
			setAtomName(pci);
			return MAL_SUCCEED;
		}
		if (idcmp("fix", name) == 0 && pci->argc == 1) {
			BATatoms[tpe].atomFix = (int (*)(const void *))pci->fcn;
			setAtomName(pci);
			return MAL_SUCCEED;
		}
		break;
	case 'h':
		if (idcmp("heap", name) == 0 && pci->argc == 1) {
			/* heap function makes an atom varsized */
			BATatoms[tpe].size = sizeof(var_t);
			assert_shift_width(ATOMelmshift(ATOMsize(tpe)), ATOMsize(tpe));
			BATatoms[tpe].atomHeap = (void (*)(Heap *, size_t))pci->fcn;
			setAtomName(pci);
			return MAL_SUCCEED;
		}
		if (idcmp("hash", name) == 0 && pci->argc == 1) {
			BATatoms[tpe].atomHash = (BUN (*)(const void *))pci->fcn;
			setAtomName(pci);
			return MAL_SUCCEED;
		}
		break;
	case 'l':
		if (idcmp("length", name) == 0 && pci->argc == 1) {
			BATatoms[tpe].atomLen = (size_t (*)(const void *))pci->fcn;
			setAtomName(pci);
			return MAL_SUCCEED;
		}
		break;
	case 'n':
		if (idcmp("null", name) == 0 && pci->argc == 1) {
			const void *atmnull = ((const void *(*)(void))pci->fcn)();

			BATatoms[tpe].atomNull = atmnull;
			setAtomName(pci);
			return MAL_SUCCEED;
		}
		if (idcmp("nequal", name) == 0 && pci->argc == 1) {
			BATatoms[tpe].atomCmp = (int (*)(const void *, const void *))pci->fcn;
			setAtomName(pci);
			return MAL_SUCCEED;
		}
		break;
	case 'p':
		if (idcmp("put", name) == 0 && pci->argc == 1) {
			BATatoms[tpe].atomPut = (var_t (*)(Heap *, var_t *, const void *))pci->fcn;
			setAtomName(pci);
			return MAL_SUCCEED;
		}
		break;
	case 's':
		if (idcmp("storage", name) == 0 && pci->argc == 1) {
			BATatoms[tpe].storage = (*(int (*)(void))pci->fcn)();
			setAtomName(pci);
			return MAL_SUCCEED;
		}
		break;
	case 't':
		if (idcmp("tostr", name) == 0 && pci->argc == 1) {
			BATatoms[tpe].atomToStr = (ssize_t (*)(str *, size_t *, const void *, bool))pci->fcn;
			setAtomName(pci);
			return MAL_SUCCEED;
		}
		break;
	case 'u':
		if (idcmp("unfix", name) == 0 && pci->argc == 1) {
			BATatoms[tpe].atomUnfix = (int (*)(const void *))pci->fcn;
			setAtomName(pci);
			return MAL_SUCCEED;
		}
		break;
	case 'r':
		if (idcmp("read", name) == 0 && pci->argc == 1) {
			BATatoms[tpe].atomRead = (void *(*)(void *, stream *, size_t))pci->fcn;
			setAtomName(pci);
			return MAL_SUCCEED;
		}
		break;
	case 'w':
		if (idcmp("write", name) == 0 && pci->argc == 1) {
			BATatoms[tpe].atomWrite = (gdk_return (*)(const void *, stream *, size_t))pci->fcn;
			setAtomName(pci);
			return MAL_SUCCEED;
		}
		break;
	}
	return MAL_SUCCEED;
}