LCOV - code coverage report
Current view: top level - tools - Kearsley.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 1 486 0.2 %
Date: 2018-12-19 07:49:13 Functions: 2 8 25.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-2018 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #include "Kearsley.h"
      23             : #include <cmath>
      24             : #include <iostream>
      25             : #include <cstdlib>
      26             : #include "Matrix.h"
      27             : #include "Tensor.h"
      28             : #include "Log.h"
      29             : #include "Matrix.h"
      30             : #include "Random.h"
      31             : 
      32             : using namespace std;
      33             : namespace PLMD {
      34             : 
      35             : // put some notes
      36             : 
      37           0 : Kearsley::Kearsley(const vector<Vector> &p0, const vector<Vector> &p1, const vector<double> &align, Log* &log):
      38             :   log(log),
      39             :   p0(p0),
      40             :   p1(p1),
      41             :   align(align),
      42             :   com0_is_removed(false),
      43             :   com1_is_removed(false),
      44           0 :   err(0.0)
      45             : {
      46             :   // now make an initial allocation
      47             : //      int n=p0.size();
      48             :   // eventually here one should make a "hard" resize of all the structures
      49             : //      log->printf("Reallocating a size of %d atoms to kearsley structure\n",n);
      50             : 
      51             : //      try{
      52             : //              diff.resize(n);
      53             : //      }catch(bad_alloc&) {
      54             : //              cerr<<"Cannot allocate the vector in Kearsley"<<endl;
      55             : //      }
      56             : //      try{
      57             : //              diff.resize(n);
      58             : //      }catch(bad_alloc&) {
      59             : //              cerr<<"Cannot allocate the vector in Kearsley"<<endl;
      60             : //      }
      61             : 
      62           0 : }
      63             : // do the alignment
      64             : 
      65           0 : double Kearsley::calculate(bool rmsd) {
      66             :   // just an ad-hoc scaling factor
      67           0 :   double myscale=1.;
      68             :   // basic sanity check
      69           0 :   if(p0.size()!=p1.size() || p1.size()!=align.size()) {
      70           0 :     cerr<<"Kearsley: looks like you have not properly allocated the vectors: the two frames have different size"<<endl;
      71           0 :     cerr<<"size of p0 is :"<<p0.size()<<endl;
      72           0 :     cerr<<"size of p1 is :"<<p1.size()<<endl;
      73           0 :     cerr<<"size of align is :"<<align.size()<<endl;
      74           0 :     exit(0);
      75             :   }
      76           0 :   if(p0.empty() || p1.empty()  ) {
      77           0 :     cerr<<"Kearsley: looks like you have not properly allocated the vectors: they do not contain anything"<<endl;
      78           0 :     exit(0);
      79             :   }
      80           0 :   Vector rr1,rr0;
      81           0 :   Vector4d q;
      82             :   double dddq[4][4][4],gamma[3][3][3],rrsq;
      83           0 :   Matrix<double> m=Matrix<double>(4,4);
      84             : //      double dm_r1[4][4][3],dm_r0[4][4][3];
      85           0 :   Vector dm_r1[4][4];
      86           0 :   Vector dm_r0[4][4];
      87           0 :   Tensor pi1,pi0;
      88           0 :   Tensor d;
      89           0 :   Tensor dinv;
      90           0 :   Vector xx;
      91           0 :   double totalign=0.,  s, tmp1, err;
      92             :   unsigned  i,j,k,l,ii,ll,jj,mm,n,nn,iii;
      93           0 :   bool verbose=false;
      94             : 
      95           0 :   vector<int> alignmap; // on the fly map done for optimization
      96             : 
      97           0 :   unsigned natoms=p0.size();
      98             : 
      99             : 
     100             :   // calculate coms
     101             : 
     102           0 :   for(i=0; i<natoms; i++) {
     103           0 :     if (align[i]>0.) {
     104           0 :       alignmap.push_back(i);
     105           0 :       totalign+=align[i];
     106             :     }
     107           0 :     if (align[i]<0.) {cerr<<"FOUND ALIGNMENT WEIGHT NEGATIVE!"<<endl; exit(0);};
     108             : 
     109             :   }
     110             : 
     111             : 
     112             :   // later will be implemented something for optimizing this piece of crap
     113             : 
     114           0 :   com0_is_removed=false;
     115           0 :   com1_is_removed=false;
     116             : 
     117           0 :   bool do_center=true; // keep it for legacy code compatibility
     118             : 
     119           0 :   if(com0_is_removed==false) {
     120             : 
     121           0 :     xx.zero();
     122             : 
     123           0 :     if(do_center) {// if you dont need to center no prob...
     124           0 :       for(i=0; i<alignmap.size(); i++) {
     125           0 :         xx+=p0[alignmap[i]]*align[alignmap[i]];
     126             :       }
     127           0 :       xx/=(totalign);
     128             :     }
     129             : 
     130           0 :     com0=xx;
     131             : 
     132           0 :     if (p0reset.empty()) {p0reset.resize(natoms);}
     133           0 :     for(i=0; i<natoms; i++) {
     134           0 :       p0reset[i]=p0[i]-xx;
     135             :     }
     136           0 :     com0_is_removed=true;
     137             : 
     138           0 :     if (verbose) {
     139           0 :       log->printf("P0 RESET\n");
     140           0 :       for(i=0; i<natoms; i++) {
     141           0 :         log->printf("ATOM %6u  C   ALA     1    %8.3f%8.3f%8.3f  1.00  1.00\n",i+1,p0reset[i][0]/myscale,p0reset[i][1]/myscale,p0reset[i][2]/myscale);
     142             :       }
     143           0 :       log->printf("END\n");
     144             :     }
     145             : 
     146             :   }
     147             : 
     148           0 :   if(com1_is_removed==false) {
     149             : 
     150           0 :     xx.zero();
     151             : 
     152           0 :     if(do_center) {// if you dont need to center no prob...
     153           0 :       for(i=0; i<alignmap.size(); i++) {
     154           0 :         xx+=p1[alignmap[i]]*align[alignmap[i]];
     155             :       }
     156           0 :       xx/=(totalign);
     157             :     }
     158             : 
     159           0 :     com1=xx;
     160             : 
     161           0 :     if (p1reset.empty()) {p1reset.resize(natoms);}
     162             : 
     163           0 :     for(i=0; i<natoms; i++) {
     164           0 :       p1reset[i]=p1[i]-xx;
     165             :     }
     166           0 :     com1_is_removed=true;
     167             : 
     168           0 :     if(verbose) {
     169           0 :       log->printf("P1 RESET\n");
     170           0 :       for(i=0; i<natoms; i++) {
     171           0 :         log->printf("ATOM %6u  C   ALA     1    %8.3f%8.3f%8.3f  1.00  1.00\n",i+1,p1reset[i][0]/myscale,p1reset[i][1]/myscale,p1reset[i][2]/myscale);
     172             :       }
     173           0 :       log->printf("END\n");
     174             :     }
     175             : 
     176             :   }
     177             : 
     178           0 :   bool fake=false;
     179           0 :   if(fake) {
     180             :     // case of trivial alignment
     181             :     // set rotmat
     182           0 :     rotmat0on1=Tensor::identity();
     183           0 :     if (p0reset.size()==0) {p0reset.resize(natoms);}
     184           0 :     if (p1reset.size()==0) {p1reset.resize(natoms);}
     185             : 
     186           0 :     derrdp0.resize(natoms);
     187           0 :     derrdp1.resize(natoms);
     188           0 :     dmatdp0.resize(3*3*3*natoms); for(i=0; i<dmatdp0.size(); i++)dmatdp0[i]=0.;
     189           0 :     dmatdp1.resize(3*3*3*natoms); for(i=0; i<dmatdp1.size(); i++)dmatdp1[i]=0.;
     190             : 
     191           0 :     err=0.;
     192           0 :     for(i=0; i<natoms; i++) {
     193           0 :       if(align[i]>0.)err+=align[i]*modulo2(p0reset[i]-p1reset[i]);
     194             :     }
     195             : 
     196           0 :     return 0.;
     197             :   }
     198             :   //
     199             :   // CLEAN M MATRIX
     200             : 
     201           0 :   m=0.;
     202             : 
     203             :   // ASSIGN MATRIX ELEMENTS USING ONLY THE ATOMS INVOLVED IN ALIGNMENT
     204             : 
     205           0 :   for(i=0; i<alignmap.size(); i++) {
     206             : 
     207           0 :     k=alignmap[i];
     208           0 :     tmp1=sqrt(align[k]/totalign);
     209             : 
     210             :     // adopt scaled coordinates
     211             : 
     212           0 :     rr1=p1reset[k]*tmp1;
     213           0 :     rr0=p0reset[k]*tmp1;
     214             : 
     215           0 :     rrsq=modulo2(rr0)+modulo2(rr1);
     216             : 
     217           0 :     m[0][0] +=  rrsq+2.*(-rr0[0]*rr1[0]-rr0[1]*rr1[1]-rr0[2]*rr1[2]);
     218           0 :     m[1][1] +=  rrsq+2.*(-rr0[0]*rr1[0]+rr0[1]*rr1[1]+rr0[2]*rr1[2]);
     219           0 :     m[2][2] +=  rrsq+2.*(+rr0[0]*rr1[0]-rr0[1]*rr1[1]+rr0[2]*rr1[2]);
     220           0 :     m[3][3] +=  rrsq+2.*(+rr0[0]*rr1[0]+rr0[1]*rr1[1]-rr0[2]*rr1[2]);
     221           0 :     m[0][1] += 2.*(-rr0[1]*rr1[2]+rr0[2]*rr1[1]);
     222           0 :     m[0][2] += 2.*( rr0[0]*rr1[2]-rr0[2]*rr1[0]);
     223           0 :     m[0][3] += 2.*(-rr0[0]*rr1[1]+rr0[1]*rr1[0]);
     224           0 :     m[1][2] -= 2.*( rr0[0]*rr1[1]+rr0[1]*rr1[0]);
     225           0 :     m[1][3] -= 2.*( rr0[0]*rr1[2]+rr0[2]*rr1[0]);
     226           0 :     m[2][3] -= 2.*( rr0[1]*rr1[2]+rr0[2]*rr1[1]);
     227             : 
     228             :   };
     229           0 :   m[1][0] = m[0][1];
     230           0 :   m[2][0] = m[0][2];
     231           0 :   m[2][1] = m[1][2];
     232           0 :   m[3][0] = m[0][3];
     233           0 :   m[3][1] = m[1][3];
     234           0 :   m[3][2] = m[2][3];
     235             : 
     236             :   // diagonalize the 4x4 matrix
     237             : 
     238           0 :   vector<double> eigenvals;
     239           0 :   Matrix<double> eigenvecs;
     240             : 
     241           0 :   int diagerror=diagMat(m, eigenvals, eigenvecs );
     242             : 
     243           0 :   if (diagerror!=0) {cerr<<"DIAGONALIZATION FAILED WITH ERROR CODE "<<diagerror<<endl; exit(0);}
     244             : 
     245           0 :   s=1.0;
     246           0 :   if(eigenvecs(0,0)<0.)s=-1.;//correct for negative values (?)
     247             :   // eigenvecs are in rows!!
     248             : 
     249           0 :   q[0]=s*eigenvecs(0,0);
     250           0 :   q[1]=s*eigenvecs(0,1);
     251           0 :   q[2]=s*eigenvecs(0,2);
     252           0 :   q[3]=s*eigenvecs(0,3);
     253           0 :   err=eigenvals[0];
     254             : 
     255             :   //log->printf(" ERR: %20.10f \n",err);
     256             : 
     257           0 :   if(verbose) {
     258           0 :     log->printf(" ERR: %f \n",err);
     259           0 :     for (i=0; i<4; i++) {
     260           0 :       log->printf(" EIGENVALS: %f \n",eigenvals[i]);
     261             :     }
     262             :   }
     263             : 
     264           0 :   if(abs(eigenvals[0]-eigenvals[1])<1.e-8) {
     265           0 :     cerr<<"DIAGONALIZATION: NON UNIQUE SOLUTION"<<endl; exit(0);
     266             :   }
     267             : 
     268             :   /*
     269             :    * the ROTATION matrix
     270             :    */
     271             : 
     272           0 :   d[0][0]=q[0]*q[0]+q[1]*q[1]-q[2]*q[2]-q[3]*q[3]       ;
     273           0 :   d[1][0]=2.0*(q[1]*q[2]-q[0]*q[3]);
     274           0 :   d[2][0]=2.0*(q[1]*q[3]+q[0]*q[2]);
     275           0 :   d[0][1]=2.0*(q[1]*q[2]+q[0]*q[3]);
     276           0 :   d[1][1]=q[0]*q[0]+q[2]*q[2]-q[1]*q[1]-q[3]*q[3];
     277           0 :   d[2][1]=2.0*(q[2]*q[3]-q[0]*q[1]);
     278           0 :   d[0][2]=2.0*(q[1]*q[3]-q[0]*q[2]);
     279           0 :   d[1][2]=2.0*(q[2]*q[3]+q[0]*q[1]);
     280           0 :   d[2][2]=q[0]*q[0]+q[3]*q[3]-q[1]*q[1]-q[2]*q[2];
     281             : 
     282             :   /*
     283             :    * first derivative in perturbation theory : derivative of the rotation matrix respect to the
     284             :    * quternion vectors
     285             :    */
     286             : 
     287           0 :   dddq[0][0][0]= 2.0*q[0];
     288           0 :   dddq[1][0][0]=-2.0*q[3];
     289           0 :   dddq[2][0][0]= 2.0*q[2];
     290           0 :   dddq[0][1][0]= 2.0*q[3];
     291           0 :   dddq[1][1][0]= 2.0*q[0];
     292           0 :   dddq[2][1][0]=-2.0*q[1];
     293           0 :   dddq[0][2][0]=-2.0*q[2];
     294           0 :   dddq[1][2][0]= 2.0*q[1];
     295           0 :   dddq[2][2][0]= 2.0*q[0];
     296             : 
     297           0 :   dddq[0][0][1]= 2.0*q[1];
     298           0 :   dddq[1][0][1]= 2.0*q[2];
     299           0 :   dddq[2][0][1]= 2.0*q[3];
     300           0 :   dddq[0][1][1]= 2.0*q[2];
     301           0 :   dddq[1][1][1]=-2.0*q[1];
     302           0 :   dddq[2][1][1]=-2.0*q[0];
     303           0 :   dddq[0][2][1]= 2.0*q[3];
     304           0 :   dddq[1][2][1]= 2.0*q[0];
     305           0 :   dddq[2][2][1]=-2.0*q[1];
     306             : 
     307           0 :   dddq[0][0][2]=-2.0*q[2];
     308           0 :   dddq[1][0][2]= 2.0*q[1];
     309           0 :   dddq[2][0][2]= 2.0*q[0];
     310           0 :   dddq[0][1][2]= 2.0*q[1];
     311           0 :   dddq[1][1][2]= 2.0*q[2];
     312           0 :   dddq[2][1][2]= 2.0*q[3];
     313           0 :   dddq[0][2][2]=-2.0*q[0];
     314           0 :   dddq[1][2][2]= 2.0*q[3];
     315           0 :   dddq[2][2][2]=-2.0*q[2];
     316             : 
     317           0 :   dddq[0][0][3]=-2.0*q[3];
     318           0 :   dddq[1][0][3]=-2.0*q[0];
     319           0 :   dddq[2][0][3]= 2.0*q[1];
     320           0 :   dddq[0][1][3]= 2.0*q[0];
     321           0 :   dddq[1][1][3]=-2.0*q[3];
     322           0 :   dddq[2][1][3]= 2.0*q[2];
     323           0 :   dddq[0][2][3]= 2.0*q[1];
     324           0 :   dddq[1][2][3]= 2.0*q[2];
     325           0 :   dddq[2][2][3]= 2.0*q[3];
     326             : 
     327             :   /*
     328             :    * Build gamma 3x3x3 matrix
     329             :    */
     330           0 :   for(i=0; i<3; i++) {  //direction
     331           0 :     for(j=0; j<3; j++) {  //direction
     332           0 :       for(k=0; k<3; k++) {  //eigenvector number
     333           0 :         gamma[i][j][k]=0.0;
     334           0 :         for(l=0; l<4; l++) { //components of each eigenvector in pert. series
     335           0 :           if(abs(eigenvals[0]-eigenvals[k+1])<1.e-8) {
     336           0 :             log->printf(" FOUND DEGENERACY IN RMSD_ESS ROUTINE \n");
     337           0 :             log->printf(" I'm DYING....\n");
     338           0 :             log->printf(" COPYING STACK HERE \n");
     339           0 :             log->printf(" P0\n");
     340           0 :             for(ll=0; ll<natoms; ll++)log->printf(" %f %f %f \n",p0reset[ll][0],p0reset[ll][1],p0reset[ll][2]);
     341           0 :             log->printf(" P1\n");
     342           0 :             for(ll=0; ll<natoms; ll++)log->printf(" %f %f %f \n",p1reset[ll][0],p1reset[ll][1],p1reset[ll][2]);
     343           0 :             exit(0);
     344             :           }
     345             :           else {
     346           0 :             gamma[i][j][k]  +=  dddq[i][j][l]*eigenvecs(k+1,l)/(eigenvals[0]-eigenvals[k+1]);
     347             :           }
     348             :         }
     349             :         //log->printf("GAMMA %2d %2d %2d V %12.6f\n",i,j,k,gamma[i][j][k]);
     350             :       }
     351             :     }
     352             :   }
     353             : 
     354             :   // allocate various arrays
     355             : 
     356           0 :   dmatdp1.resize(3*3*3*natoms);
     357           0 :   for(i=0; i<dmatdp1.size(); i++)dmatdp1[i]=0.;
     358           0 :   dmatdp0.resize(3*3*3*natoms);
     359           0 :   for(i=0; i<dmatdp0.size(); i++)dmatdp0[i]=0.;
     360             : 
     361           0 :   vector<double> dd_dr_temp; dd_dr_temp.resize(natoms);
     362             : 
     363           0 :   vector<Vector> derr_dr1;
     364           0 :   derr_dr1.resize(natoms);
     365           0 :   vector<Vector> derr_dr0;
     366           0 :   derr_dr0.resize(natoms);
     367           0 :   vector<Vector> array_3_n;
     368           0 :   array_3_n.resize(natoms);
     369             : 
     370             : 
     371             :   /*
     372             :    * Table of Derivative of the quaternion matrix respect to atom position: needed only if simple
     373             :    * alignment is required and no correction respect to the rotation matrix is wanted
     374             :    */
     375             : 
     376           0 :   for(iii=0; iii<alignmap.size(); iii++) {
     377             : 
     378           0 :     i=alignmap[iii];
     379           0 :     tmp1=sqrt(align[i]/totalign);
     380             : 
     381             :     // once again: derivative respect to scaled distance
     382             : 
     383           0 :     rr1=2.*p1reset[i]*tmp1;
     384           0 :     rr0=2.*p0reset[i]*tmp1;
     385             : 
     386             : 
     387           0 :     dm_r1 [0][0][0]=(rr1[0]-rr0[0]);
     388           0 :     dm_r1 [0][0][1]=(rr1[1]-rr0[1]);
     389           0 :     dm_r1 [0][0][2]=(rr1[2]-rr0[2]);
     390             : 
     391           0 :     dm_r1 [0][1][0]=0.;
     392           0 :     dm_r1 [0][1][1]= rr0[2];
     393           0 :     dm_r1 [0][1][2]=-rr0[1];
     394             : 
     395           0 :     dm_r1 [0][2][0]=-rr0[2];
     396           0 :     dm_r1 [0][2][1]= 0.;
     397           0 :     dm_r1 [0][2][2]= rr0[0];
     398             : 
     399           0 :     dm_r1 [0][3][0]= rr0[1];
     400           0 :     dm_r1 [0][3][1]=-rr0[0];
     401           0 :     dm_r1 [0][3][2]= 0.;
     402             : 
     403           0 :     dm_r1 [1][1][0]=(rr1[0]-rr0[0]);
     404           0 :     dm_r1 [1][1][1]=(rr1[1]+rr0[1]);
     405           0 :     dm_r1 [1][1][2]=(rr1[2]+rr0[2]);
     406             : 
     407           0 :     dm_r1 [1][2][0]=-rr0[1];
     408           0 :     dm_r1 [1][2][1]=-rr0[0];
     409           0 :     dm_r1 [1][2][2]= 0.;
     410             : 
     411           0 :     dm_r1 [1][3][0]=-rr0[2];
     412           0 :     dm_r1 [1][3][1]= 0.;
     413           0 :     dm_r1 [1][3][2]=-rr0[0];
     414             : 
     415           0 :     dm_r1 [2][2][0]=(rr1[0]+rr0[0]);
     416           0 :     dm_r1 [2][2][1]=(rr1[1]-rr0[1]);
     417           0 :     dm_r1 [2][2][2]=(rr1[2]+rr0[2]);
     418             : 
     419           0 :     dm_r1 [2][3][0]=0.;
     420           0 :     dm_r1 [2][3][1]=-rr0[2];
     421           0 :     dm_r1 [2][3][2]=-rr0[1];
     422             : 
     423           0 :     dm_r1 [3][3][0]=(rr1[0]+rr0[0]);
     424           0 :     dm_r1 [3][3][1]=(rr1[1]+rr0[1]);
     425           0 :     dm_r1 [3][3][2]=(rr1[2]-rr0[2]);
     426             :     /*
     427             :     derivative respec to to the other vector
     428             :      */
     429           0 :     dm_r0 [0][0][0]=-(rr1[0]-rr0[0]);
     430           0 :     dm_r0 [0][0][1]=-(rr1[1]-rr0[1]);
     431           0 :     dm_r0 [0][0][2]=-(rr1[2]-rr0[2]);
     432             : 
     433           0 :     dm_r0 [0][1][0]=0.       ;
     434           0 :     dm_r0 [0][1][1]=-rr1[2];
     435           0 :     dm_r0 [0][1][2]=rr1[1];
     436             : 
     437           0 :     dm_r0 [0][2][0]= rr1[2];
     438           0 :     dm_r0 [0][2][1]= 0.;
     439           0 :     dm_r0 [0][2][2]=-rr1[0];
     440             : 
     441           0 :     dm_r0 [0][3][0]=-rr1[1] ;
     442           0 :     dm_r0 [0][3][1]= rr1[0];
     443           0 :     dm_r0 [0][3][2]= 0.;
     444             : 
     445           0 :     dm_r0 [1][1][0]=-(rr1[0]-rr0[0]);
     446           0 :     dm_r0 [1][1][1]=(rr1[1]+rr0[1]);
     447           0 :     dm_r0 [1][1][2]=(rr1[2]+rr0[2]);
     448             : 
     449           0 :     dm_r0 [1][2][0]=-rr1[1];
     450           0 :     dm_r0 [1][2][1]=-rr1[0];
     451           0 :     dm_r0 [1][2][2]= 0.;
     452             : 
     453           0 :     dm_r0 [1][3][0]=-rr1[2];
     454           0 :     dm_r0 [1][3][1]= 0.;
     455           0 :     dm_r0 [1][3][2]=-rr1[0];
     456             : 
     457           0 :     dm_r0 [2][2][0]=(rr1[0]+rr0[0]);
     458           0 :     dm_r0 [2][2][1]=-(rr1[1]-rr0[1]);
     459           0 :     dm_r0 [2][2][2]=(rr1[2]+rr0[2]);
     460             : 
     461           0 :     dm_r0 [2][3][0]=0.;
     462           0 :     dm_r0 [2][3][1]=-rr1[2];
     463           0 :     dm_r0 [2][3][2]=-rr1[1];
     464             : 
     465           0 :     dm_r0 [3][3][0]=(rr1[0]+rr0[0]);
     466           0 :     dm_r0 [3][3][1]=(rr1[1]+rr0[1]);
     467           0 :     dm_r0 [3][3][2]=-(rr1[2]-rr0[2]);
     468             :     /*
     469             :      * write the diagonal
     470             :      */
     471             : 
     472           0 :     dm_r1[1][0]=dm_r1[0][1];
     473           0 :     dm_r1[2][0]=dm_r1[0][2];
     474           0 :     dm_r1[3][0]=dm_r1[0][3];
     475           0 :     dm_r1[2][1]=dm_r1[1][2];
     476           0 :     dm_r1[3][1]=dm_r1[1][3];
     477           0 :     dm_r1[3][2]=dm_r1[2][3];
     478             : 
     479           0 :     dm_r0[1][0]=dm_r0[0][1];
     480           0 :     dm_r0[2][0]=dm_r0[0][2];
     481           0 :     dm_r0[3][0]=dm_r0[0][3];
     482           0 :     dm_r0[2][1]=dm_r0[1][2];
     483           0 :     dm_r0[3][1]=dm_r0[1][3];
     484           0 :     dm_r0[3][2]=dm_r0[2][3];
     485             : 
     486             : 
     487             :     //log->printf("DMDR0 ALIGN %f AT %d VAL %f\n",align[i],i,dm_r0[0][0][j]);
     488             : 
     489             : 
     490             :     /*
     491             :      * pi matrix : coefficents in per theory
     492             :      */
     493             : 
     494           0 :     pi0.zero();
     495           0 :     pi1.zero();
     496           0 :     derr_dr1[i].zero();
     497           0 :     derr_dr0[i].zero();
     498             : 
     499           0 :     for(k=0; k<4; k++) {
     500           0 :       for(l=0; l<4; l++) {
     501           0 :         derr_dr1[i]+=(q[k]*q[l])*dm_r1[l][k];
     502           0 :         derr_dr0[i]+=(q[k]*q[l])*dm_r0[l][k];
     503           0 :         for(mm=0; mm<3; mm++)for(j=0; j<3; j++) {
     504           0 :             pi0[mm][j]+=eigenvecs(mm+1,k)*dm_r0[l][k][j]*q[l];
     505           0 :             pi1[mm][j]+=eigenvecs(mm+1,k)*dm_r1[l][k][j]*q[l];
     506             :           };
     507             :       };
     508             :     };
     509             :     /*
     510             :                 derr_dr1[i]/=totalign;
     511             :                 derr_dr0[i]/=totalign;
     512             : 
     513             : 
     514             :     */
     515             : 
     516           0 :     for(j=0; j<3; j++) {
     517           0 :       for (k=0; k<3; k++) {
     518           0 :         for(l=0; l<3; l++) {
     519           0 :           int ind=j*3*3*natoms+k*3*natoms+l*natoms+i;
     520           0 :           dmatdp0[ind]=0.;
     521           0 :           dmatdp1[ind]=0.;
     522           0 :           for(ii=0; ii<3; ii++) {
     523           0 :             dmatdp1[ind]+=gamma[j][k][ii]*pi1[ii][l];
     524           0 :             dmatdp0[ind]+=gamma[j][k][ii]*pi0[ii][l];
     525             :           }
     526             : 
     527             :         }
     528             : 
     529             :       }
     530             : 
     531             :     }
     532             :   }
     533             : 
     534             : 
     535             : 
     536             : 
     537             :   // end of the calculation of the derivative of the rotation matrix
     538             : 
     539             :   /*
     540             :    * Now correct for center of mass: only if needed
     541             :    *
     542             :    */
     543             : 
     544           0 :   bool comcorr_r1=true;
     545             : 
     546           0 :   if(comcorr_r1) {
     547           0 :     for(k=0; k<alignmap.size(); k++) {
     548           0 :       i=alignmap[k];
     549           0 :       tmp1=sqrt(align[i]/totalign);
     550           0 :       array_3_n[i]=tmp1*derr_dr1[i];
     551           0 :       if(do_center) {
     552           0 :         for(jj=0; jj<alignmap.size(); jj++) {
     553           0 :           j=alignmap[jj];
     554           0 :           array_3_n[i]-=tmp1*(align[j]/totalign)*derr_dr1[j];
     555             :         }
     556             :       }
     557             :     }
     558           0 :     for(k=0; k<alignmap.size(); k++) {
     559           0 :       i=alignmap[k];
     560           0 :       derr_dr1[i]=array_3_n[i];
     561             :     }
     562             :   }
     563             : 
     564             : 
     565           0 :   bool do_comcorr_r0=true;
     566             :   //
     567             :   // correction for r0 frame
     568             :   //
     569           0 :   if(do_comcorr_r0) {
     570           0 :     for(k=0; k<alignmap.size(); k++) {
     571           0 :       i=alignmap[k];
     572           0 :       tmp1=sqrt(align[i]/totalign);
     573           0 :       array_3_n[i]=tmp1*derr_dr0[i];
     574           0 :       if(do_center) {
     575           0 :         for(jj=0; jj<alignmap.size(); jj++) {
     576           0 :           j=alignmap[jj];
     577           0 :           array_3_n[i]-=tmp1*(align[j]/totalign)*derr_dr0[j];
     578             :         }
     579             :       }
     580             :     }
     581           0 :     for(k=0; k<alignmap.size(); k++) {
     582           0 :       i=alignmap[k];
     583           0 :       derr_dr0[i]=array_3_n[i];
     584             :     }
     585             :   }
     586             : 
     587             : 
     588           0 :   bool do_der_r1=true;
     589           0 :   bool do_der_r0=true;
     590           0 :   bool do_der_rotmat=true;
     591             : 
     592           0 :   if(do_der_r1 && do_der_rotmat) {
     593           0 :     for(i=0; i<3; i++) {
     594           0 :       for(j=0; j<3; j++) {
     595           0 :         for(k=0; k<3; k++) {
     596           0 :           for(ll=0; ll<alignmap.size(); ll++) {
     597           0 :             l=alignmap[ll];
     598           0 :             int ind=i*3*3*natoms+j*3*natoms+k*natoms+l;
     599           0 :             tmp1=sqrt(align[l]/totalign);
     600           0 :             dd_dr_temp[l]=tmp1*dmatdp1[ind];
     601           0 :             if(do_center) {
     602           0 :               for(nn=0; nn<alignmap.size(); nn++) {
     603           0 :                 n=alignmap[nn];
     604           0 :                 dd_dr_temp[l]-=dmatdp1[ind-l+n]*tmp1*align[n]/totalign;
     605             :               }
     606             :             }
     607             : 
     608             :           }
     609           0 :           for(ll=0; ll<alignmap.size(); ll++) {
     610           0 :             l=alignmap[ll];
     611           0 :             int ind=i*3*3*natoms+j*3*natoms+k*natoms+l;
     612           0 :             dmatdp1[ind]=dd_dr_temp[l];
     613             :           }
     614             : 
     615             :         }
     616             :       }
     617             :     }
     618             : 
     619             :   }
     620             : 
     621           0 :   if(do_der_r0 && do_der_rotmat) {
     622           0 :     for(i=0; i<3; i++) {
     623           0 :       for(j=0; j<3; j++) {
     624           0 :         for(k=0; k<3; k++) {
     625           0 :           for(ll=0; ll<alignmap.size(); ll++) {
     626           0 :             l=alignmap[ll];
     627           0 :             int ind=i*3*3*natoms+j*3*natoms+k*natoms+l;
     628           0 :             tmp1=sqrt(align[l]/totalign);
     629           0 :             dd_dr_temp[l]=tmp1*dmatdp0[ind];
     630           0 :             if(do_center) {
     631           0 :               for(nn=0; nn<alignmap.size(); nn++) {
     632           0 :                 n=alignmap[nn];
     633           0 :                 dd_dr_temp[l]-=dmatdp0[ind-l+n]*tmp1*align[n]/totalign;
     634             :               }
     635             :             }
     636             :           }
     637           0 :           for(ll=0; ll<alignmap.size(); ll++) {
     638           0 :             l=alignmap[ll];
     639           0 :             int ind=i*3*3*natoms+j*3*natoms+k*natoms+l;
     640           0 :             dmatdp0[ind]=dd_dr_temp[l];
     641             :           }
     642             :         }
     643             :       }
     644             :     }
     645             :   }
     646             : 
     647             : 
     648           0 :   bool do_p1rotated=true;
     649           0 :   if (do_p1rotated) {
     650             :     // resize if not allocated
     651             : 
     652           0 :     if(p1.size()!=p1rotated.size())p1rotated.resize(p1.size());
     653             : 
     654             : //              exit(0);
     655             : 
     656           0 :     for(i=0; i<natoms; i++) p1rotated[i]=matmul(d,p1reset[i]);
     657             : 
     658             :     // reallocate difference vectors
     659           0 :     if(p1.size()!=diff1on0.size())diff1on0.resize(p1.size());
     660           0 :     for(i=0; i<natoms; i++) {
     661           0 :       diff1on0[i]=p1rotated[i]-p0reset[i];
     662             :     }
     663             : 
     664           0 :     if(verbose) {
     665           0 :       log->printf("P1-RESET-AND-ROTATED\n");
     666           0 :       for(i=0; i<natoms; i++) {
     667           0 :         log->printf("ATOM %6u  C   ALA     2    %8.3f%8.3f%8.3f  1.00  1.00\n",i+1,p1rotated[i][0]/myscale,p1rotated[i][1]/myscale,p1rotated[i][2]/myscale);
     668             :       }
     669           0 :       log->printf("END\n");
     670           0 :       log->printf("P0-RESET\n");
     671           0 :       for(i=0; i<natoms; i++) {
     672           0 :         log->printf("ATOM %6u  C   ALA     2    %8.3f%8.3f%8.3f  1.00  1.00\n",i+1,p0reset[i][0]/myscale,p0reset[i][1]/myscale,p0reset[i][2]/myscale);
     673             :       }
     674           0 :       log->printf("END\n");
     675             :     }
     676             : 
     677             :   }
     678             : 
     679             : 
     680             : 
     681           0 :   dinv=inverse(d);
     682             : 
     683           0 :   bool do_p0rotated=true;
     684           0 :   if (do_p0rotated) {
     685           0 :     if(p0.size()!=p0rotated.size())p0rotated.resize(p0.size());
     686           0 :     for(i=0; i<natoms; i++) p0rotated[i]=matmul(dinv,p0reset[i]);
     687           0 :     if(p1.size()!=diff0on1.size())diff0on1.resize(p1.size());
     688           0 :     for(i=0; i<natoms; i++) diff0on1[i]=p0rotated[i]-p1reset[i];
     689           0 :     if(verbose) {
     690           0 :       log->printf("P0-RESET AND INVERSE ROTATED\n");
     691           0 :       for(i=0; i<natoms; i++) {
     692           0 :         log->printf("ATOM %6u  C   ALA     1    %8.3f%8.3f%8.3f  1.00  1.00\n",i+1,p0rotated[i][0]/myscale,p0rotated[i][1]/myscale,p0rotated[i][2]/myscale);
     693             :       }
     694           0 :       log->printf("END\n");
     695           0 :       log->printf("P1-RESET\n");
     696           0 :       for(i=0; i<natoms; i++) {
     697           0 :         log->printf("ATOM %6u  C   ALA     2    %8.3f%8.3f%8.3f  1.00  1.00\n",i+1,p1reset[i][0]/myscale,p1reset[i][1]/myscale,p1reset[i][2]/myscale);
     698             :       }
     699           0 :       log->printf("END\n");
     700             :     }
     701             :   }
     702             :   // copy on the official vectors:
     703           0 :   rotmat0on1=d;
     704           0 :   rotmat1on0=dinv;
     705           0 :   derrdp0.resize(natoms);
     706           0 :   derrdp0=derr_dr0;
     707           0 :   derrdp1.resize(natoms);
     708           0 :   derrdp1=derr_dr1;
     709             : 
     710             :   // now rescale accordingly for rmsd instead of msd
     711           0 :   if(rmsd) {
     712           0 :     err=sqrt(err);
     713           0 :     double tmp=0.5/err;
     714           0 :     for(ii=0; ii<alignmap.size(); ii++) {
     715           0 :       i=alignmap[ii];
     716           0 :       derrdp0[i]*=tmp;
     717           0 :       derrdp1[i]*=tmp;
     718             :     }
     719             : 
     720             :   }
     721             : 
     722           0 :   return err;
     723             : 
     724             : }
     725           0 : void Kearsley::assignP1(const std::vector<Vector> & p1) {
     726           0 :   this->p1=p1;
     727           0 :   com1_is_removed=false;
     728           0 : }
     729           0 : void Kearsley::assignP0(const std::vector<Vector> & p0) {
     730           0 :   this->p0=p0;
     731           0 :   com0_is_removed=false;
     732           0 : }
     733             : 
     734           0 : void Kearsley::assignAlign(const std::vector<double> & align) {
     735           0 :   this->align=align;
     736           0 : }
     737             : 
     738           0 : void Kearsley::finiteDifferenceInterface(bool rmsd) {
     739           0 :   log->printf("Entering rmsd finite difference test system for kearsley\n");
     740           0 :   log->printf("-------------------------------------------\n");
     741           0 :   log->printf("TEST1: derivative of the value (derr_dr0/derr_dr1)\n");
     742             : //// test 1
     743             :   unsigned i,j,l,m;
     744           0 :   double step=1.e-6,olderr,delta;
     745             : // messing up a bit with align weights
     746             :   double delta1;
     747           0 :   vector<double> align1;
     748           0 :   align1.resize(p0.size());
     749           0 :   Random rnd;
     750           0 :   for (i=0; i<p0.size(); i++) {
     751             :     // draw a random number
     752           0 :     delta=rnd.RandU01();
     753           0 :     delta1=rnd.RandU01();
     754           0 :     if(delta>delta1) {
     755             :       //if(delta>0.3){
     756           0 :       align1[i]=delta;
     757           0 :     } else {align1[i]=0.;};
     758             :     // log->printf("ALIGN %d IS %8.3f\n",i,align1[i]);
     759             :   }
     760           0 :   assignAlign(align1);
     761             : //// get initial value of the error and derivative of it
     762           0 :   olderr=calculate(rmsd);
     763           0 :   log->printf("INITIAL ERROR VALUE: %e\n",olderr);
     764             : // store the matrix
     765           0 :   Tensor old_rotmat0on1=rotmat0on1;
     766             : 
     767             : //// get initial value of the error and derivative of it
     768             : 
     769           0 :   log->printf("TESTING: derrdp1 \n");
     770           0 :   for(unsigned j=0; j<3; j++) {
     771           0 :     for(unsigned i=0; i<derrdp1.size(); i++) {
     772             :       // random displacement
     773           0 :       delta=(rnd.RandU01()-0.5)*2*step;
     774           0 :       p1[i][j]+=delta;
     775           0 :       com1_is_removed=false; // this is required whenever the assignment is not done with the methods
     776           0 :       com0_is_removed=false; // this is required whenever the assignment is not done with the methods
     777           0 :       err=calculate(rmsd);
     778             :       //log->printf("INITIAL ERROR VALUE: %e NEW ERROR %e DELTA %e ELEM %d %d \n",olderr,err,delta,i,j );
     779           0 :       p1[i][j]-=delta;
     780           0 :       switch(j) {
     781             :       case 0:
     782           0 :         log->printf("TESTING: X  %4u ANAL %18.9f NUMER %18.9f DELTA %18.9f ALIGN %6.2f\n",i,derrdp1[i][j],(err-olderr)/delta,derrdp1[i][j]-(err-olderr)/delta,align[i]); break;
     783             :       case 1:
     784           0 :         log->printf("TESTING: Y  %4u ANAL %18.9f NUMER %18.9f DELTA %18.9f ALIGN %6.2f\n",i,derrdp1[i][j],(err-olderr)/delta,derrdp1[i][j]-(err-olderr)/delta,align[i]); break;
     785             :       case 2:
     786           0 :         log->printf("TESTING: Z  %4u ANAL %18.9f NUMER %18.9f DELTA %18.9f ALIGN %6.2f\n",i,derrdp1[i][j],(err-olderr)/delta,derrdp1[i][j]-(err-olderr)/delta,align[i]); break;
     787             : 
     788             :       }
     789             :     }
     790             :   }
     791             : //exit(0);
     792           0 :   log->printf("TESTING: derrdp0 \n");
     793           0 :   for(unsigned j=0; j<3; j++) {
     794           0 :     for(unsigned i=0; i<derrdp0.size(); i++) {
     795             :       // random displacement
     796           0 :       delta=(rnd.RandU01()-0.5)*2*step;
     797           0 :       p0[i][j]+=delta;
     798           0 :       com0_is_removed=false; // this is required whenever the assignment is not done with the methods
     799           0 :       com1_is_removed=false; // this is required whenever the assignment is not done with the methods
     800             : 
     801           0 :       err=calculate(rmsd);
     802           0 :       p0[i][j]-=delta;
     803           0 :       switch(j) {
     804             :       case 0:
     805           0 :         log->printf("TESTING: X  %4u ANAL %18.9f NUMER %18.9f DELTA %18.9f ALIGN %6.2f\n",i,derrdp0[i][j],(err-olderr)/delta,derrdp0[i][j]-(err-olderr)/delta,align[i]); break;
     806             :       case 1:
     807           0 :         log->printf("TESTING: Y  %4u ANAL %18.9f NUMER %18.9f DELTA %18.9f ALIGN %6.2f\n",i,derrdp0[i][j],(err-olderr)/delta,derrdp0[i][j]-(err-olderr)/delta,align[i]); break;
     808             :       case 2:
     809           0 :         log->printf("TESTING: Z  %4u ANAL %18.9f NUMER %18.9f DELTA %18.9f ALIGN %6.2f\n",i,derrdp0[i][j],(err-olderr)/delta,derrdp0[i][j]-(err-olderr)/delta,align[i]); break;
     810             :       }
     811             :     }
     812             :   }
     813             : 
     814           0 :   log->printf("TESTING: dmatdp0 \n");
     815           0 :   for(l=0; l<3; l++) {
     816           0 :     for(m=0; m<3; m++) {
     817           0 :       for(j=0; j<3; j++) {
     818           0 :         for(i=0; i<p0.size(); i++) {
     819             :           // random displacement
     820           0 :           delta=(rnd.RandU01()-0.5)*2*step;
     821           0 :           p0[i][j]+=delta;
     822           0 :           com0_is_removed=false;
     823           0 :           com1_is_removed=false;
     824           0 :           calculate(rmsd);
     825           0 :           p0[i][j]-=delta;
     826           0 :           int ind=l*3*3*p0.size()+m*3*p0.size()+j*p0.size()+i;
     827           0 :           switch(j) {
     828             :           case 0:
     829           0 :             log->printf("TESTING: DMATDP0 [ %u ][ %u ]:  X %u ANAL %18.9f NUMER %18.9f DELTA %18.9f ALIGN %6.2f\n",l,m,i,dmatdp0[ind],(rotmat0on1[l][m]- old_rotmat0on1[l][m])/delta,dmatdp0[ind]-(rotmat0on1[l][m]- old_rotmat0on1[l][m])/delta,align[i]); break;
     830             : 
     831             :           case 1:
     832           0 :             log->printf("TESTING: DMATDP0 [ %u ][ %u ]:  Y %u ANAL %18.9f NUMER %18.9f DELTA %18.9f ALIGN %6.2f\n",l,m,i,dmatdp0[ind],(rotmat0on1[l][m]- old_rotmat0on1[l][m])/delta,dmatdp0[ind]-(rotmat0on1[l][m]- old_rotmat0on1[l][m])/delta,align[i]); break;
     833             : 
     834             :           case 2:
     835           0 :             log->printf("TESTING: DMATDP0 [ %u ][ %u ]:  Z %u ANAL %18.9f NUMER %18.9f DELTA %18.9f ALIGN %6.2f\n",l,m,i,dmatdp0[ind],(rotmat0on1[l][m]- old_rotmat0on1[l][m])/delta,dmatdp0[ind]-(rotmat0on1[l][m]- old_rotmat0on1[l][m])/delta,align[i]); break;
     836             : 
     837             :           }
     838             :         }
     839             :       }
     840             :     }
     841             :   }
     842           0 :   log->printf("TESTING: dmatdp1 \n");
     843           0 :   for(l=0; l<3; l++) {
     844           0 :     for(m=0; m<3; m++) {
     845           0 :       for(j=0; j<3; j++) {
     846           0 :         for(i=0; i<p1.size(); i++) {
     847             :           // random displacement
     848           0 :           delta=(rnd.RandU01()-0.5)*2*step;
     849           0 :           p1[i][j]+=delta;
     850           0 :           com0_is_removed=false;
     851           0 :           com1_is_removed=false;
     852           0 :           calculate(rmsd);
     853           0 :           p1[i][j]-=delta;
     854           0 :           int ind=l*3*3*p1.size()+m*3*p1.size()+j*p1.size()+i;
     855           0 :           switch(j) {
     856             : 
     857             :           case 0:
     858           0 :             log->printf("TESTING: DMATDP1 [ %u ][ %u ]:  X %u ANAL %18.9f NUMER %18.9f DELTA %18.9f ALIGN %6.2f\n",l,m,i,dmatdp1[ind],(rotmat0on1[l][m]- old_rotmat0on1[l][m])/delta,dmatdp1[ind]-(rotmat0on1[l][m]- old_rotmat0on1[l][m])/delta,align[i]); break;
     859             : 
     860             :           case 1:
     861           0 :             log->printf("TESTING: DMATDP1 [ %u ][ %u ]:  Y %u ANAL %18.9f NUMER %18.9f DELTA %18.9f ALIGN %6.2f\n",l,m,i,dmatdp1[ind],(rotmat0on1[l][m]- old_rotmat0on1[l][m])/delta,dmatdp1[ind]-(rotmat0on1[l][m]- old_rotmat0on1[l][m])/delta,align[i]); break;
     862             : 
     863             :           case 2:
     864           0 :             log->printf("TESTING: DMATDP1 [ %u ][ %u ]:  Z %u ANAL %18.9f NUMER %18.9f DELTA %18.9f ALIGN %6.2f\n",l,m,i,dmatdp1[ind],(rotmat0on1[l][m]- old_rotmat0on1[l][m])/delta,dmatdp1[ind]-(rotmat0on1[l][m]- old_rotmat0on1[l][m])/delta,align[i]); break;
     865             : 
     866             :           }
     867             :         }
     868             :       }
     869             :     }
     870             :   }
     871             : 
     872           0 :   exit(0);
     873             : }
     874        2523 : }

Generated by: LCOV version 1.13