double MultiDomainRMSD::calculate( const std::vector<Vector>& pos, const Pbc& pbc, const bool& squared ){ clearDerivatives(); double totd=0.; Tensor tvirial; std::vector<Vector> mypos; for(unsigned i=0;i<domains.size();++i){ // Must extract appropriate positions here mypos.resize( blocks[i+1] - blocks[i] + 1 ); unsigned n=0; for(unsigned j=blocks[i];j<blocks[i+1];++j){ mypos[n]=pos[j]; n++; } // This actually does the calculation totd += weights[i]*domains[i]->calculate( mypos, pbc, true ); // Must extract derivatives here n=0; for(unsigned j=blocks[i];j<blocks[i+1];++j){ addAtomicDerivatives( j, weights[i]*domains[i]->getAtomDerivative(n) ); n++; } if( domains[i]->getVirial( tvirial ) ){ addBoxDerivatives( weights[i]*tvirial ); } } if( !squared ){ totd=sqrt(totd); double xx=0.5/totd; for(unsigned iat=0;iat<atom_ders.size();iat++) atom_ders[iat]*=xx; if( virialWasSet ) virial*=xx; } return totd; }
double SingleDomainRMSD::calculate( const std::vector<Vector>& pos, const Pbc& pbc, const bool& squared ){ clearDerivatives(); return calc( pos, pbc, squared ); }
double ArgumentOnlyDistance::calculate( const std::vector<Value*>& vals, const bool& squared ){ clearDerivatives(); if( tmparg.size()!=vals.size() ) tmparg.resize( vals.size() ); for(unsigned i=0;i<vals.size();++i) tmparg[i]=vals[i]->get(); return calc( vals, tmparg, squared ); }
double RMSDBase::calculate( const std::vector<Vector>& pos, const bool& squared ){ clearDerivatives(); return calc( pos, squared ); }