37 Kearsley::Kearsley(
const vector<Vector> &p0,
const vector<Vector> &p1,
const vector<double> &align,
Log* &log):
42 com0_is_removed(false),
43 com1_is_removed(false),
69 if(
p0.size()!=
p1.size() ||
p1.size()!=
align.size()){
70 cerr<<
"Kearsley: looks like you have not properly allocated the vectors: the two frames have different size"<<endl;
71 cerr<<
"size of p0 is :"<<
p0.size()<<endl;
72 cerr<<
"size of p1 is :"<<
p1.size()<<endl;
73 cerr<<
"size of align is :"<<
align.size()<<endl;
76 if(
p0.empty() ||
p1.empty() ){
77 cerr<<
"Kearsley: looks like you have not properly allocated the vectors: they do not contain anything"<<endl;
82 double dddq[4][4][4],gamma[3][3][3],rrsq;
91 double totalign=0., s, tmp1,
err;
92 unsigned i,j,k,l,ii,ll,jj,mm,
n,nn,iii;
97 unsigned natoms=
p0.size();
102 for(i=0;i<natoms;i++){
104 alignmap.push_back(i);
107 if (
align[i]<0.){cerr<<
"FOUND ALIGNMENT WEIGHT NEGATIVE!"<<endl;exit(0);};
124 for(i=0;i<alignmap.size();i++){
125 xx+=
p0[alignmap[i]]*
align[alignmap[i]];
133 for(i=0;i<natoms;i++){
140 for(i=0;i<natoms;i++){
153 for(i=0;i<alignmap.size();i++){
154 xx+=
p1[alignmap[i]]*
align[alignmap[i]];
163 for(i=0;i<natoms;i++){
170 for(i=0;i<natoms;i++){
192 for(i=0;i<natoms;i++){
205 for(i=0;i<alignmap.size();i++){
208 tmp1=sqrt(
align[k]/totalign);
217 m[0][0] += rrsq+2.*(-rr0[0]*rr1[0]-rr0[1]*rr1[1]-rr0[2]*rr1[2]);
218 m[1][1] += rrsq+2.*(-rr0[0]*rr1[0]+rr0[1]*rr1[1]+rr0[2]*rr1[2]);
219 m[2][2] += rrsq+2.*(+rr0[0]*rr1[0]-rr0[1]*rr1[1]+rr0[2]*rr1[2]);
220 m[3][3] += rrsq+2.*(+rr0[0]*rr1[0]+rr0[1]*rr1[1]-rr0[2]*rr1[2]);
221 m[0][1] += 2.*(-rr0[1]*rr1[2]+rr0[2]*rr1[1]);
222 m[0][2] += 2.*( rr0[0]*rr1[2]-rr0[2]*rr1[0]);
223 m[0][3] += 2.*(-rr0[0]*rr1[1]+rr0[1]*rr1[0]);
224 m[1][2] -= 2.*( rr0[0]*rr1[1]+rr0[1]*rr1[0]);
225 m[1][3] -= 2.*( rr0[0]*rr1[2]+rr0[2]*rr1[0]);
226 m[2][3] -= 2.*( rr0[1]*rr1[2]+rr0[2]*rr1[1]);
238 vector<double> eigenvals;
241 int diagerror=
diagMat(m, eigenvals, eigenvecs );
243 if (diagerror!=0){cerr<<
"DIAGONALIZATION FAILED WITH ERROR CODE "<<diagerror<<endl;exit(0);}
246 if(eigenvecs(0,0)<0.)s=-1.;
249 q[0]=s*eigenvecs(0,0);
250 q[1]=s*eigenvecs(0,1);
251 q[2]=s*eigenvecs(0,2);
252 q[3]=s*eigenvecs(0,3);
260 log->
printf(
" EIGENVALS: %f \n",eigenvals[i]);
264 if(abs(eigenvals[0]-eigenvals[1])<1.e-8){
265 cerr<<
"DIAGONALIZATION: NON UNIQUE SOLUTION"<<endl;exit(0);
272 d[0][0]=q[0]*q[0]+q[1]*q[1]-q[2]*q[2]-q[3]*q[3] ;
273 d[1][0]=2.0*(q[1]*q[2]-q[0]*q[3]);
274 d[2][0]=2.0*(q[1]*q[3]+q[0]*q[2]);
275 d[0][1]=2.0*(q[1]*q[2]+q[0]*q[3]);
276 d[1][1]=q[0]*q[0]+q[2]*q[2]-q[1]*q[1]-q[3]*q[3];
277 d[2][1]=2.0*(q[2]*q[3]-q[0]*q[1]);
278 d[0][2]=2.0*(q[1]*q[3]-q[0]*q[2]);
279 d[1][2]=2.0*(q[2]*q[3]+q[0]*q[1]);
280 d[2][2]=q[0]*q[0]+q[3]*q[3]-q[1]*q[1]-q[2]*q[2];
287 dddq[0][0][0]= 2.0*q[0];
288 dddq[1][0][0]=-2.0*q[3];
289 dddq[2][0][0]= 2.0*q[2];
290 dddq[0][1][0]= 2.0*q[3];
291 dddq[1][1][0]= 2.0*q[0];
292 dddq[2][1][0]=-2.0*q[1];
293 dddq[0][2][0]=-2.0*q[2];
294 dddq[1][2][0]= 2.0*q[1];
295 dddq[2][2][0]= 2.0*q[0];
297 dddq[0][0][1]= 2.0*q[1];
298 dddq[1][0][1]= 2.0*q[2];
299 dddq[2][0][1]= 2.0*q[3];
300 dddq[0][1][1]= 2.0*q[2];
301 dddq[1][1][1]=-2.0*q[1];
302 dddq[2][1][1]=-2.0*q[0];
303 dddq[0][2][1]= 2.0*q[3];
304 dddq[1][2][1]= 2.0*q[0];
305 dddq[2][2][1]=-2.0*q[1];
307 dddq[0][0][2]=-2.0*q[2];
308 dddq[1][0][2]= 2.0*q[1];
309 dddq[2][0][2]= 2.0*q[0];
310 dddq[0][1][2]= 2.0*q[1];
311 dddq[1][1][2]= 2.0*q[2];
312 dddq[2][1][2]= 2.0*q[3];
313 dddq[0][2][2]=-2.0*q[0];
314 dddq[1][2][2]= 2.0*q[3];
315 dddq[2][2][2]=-2.0*q[2];
317 dddq[0][0][3]=-2.0*q[3];
318 dddq[1][0][3]=-2.0*q[0];
319 dddq[2][0][3]= 2.0*q[1];
320 dddq[0][1][3]= 2.0*q[0];
321 dddq[1][1][3]=-2.0*q[3];
322 dddq[2][1][3]= 2.0*q[2];
323 dddq[0][2][3]= 2.0*q[1];
324 dddq[1][2][3]= 2.0*q[2];
325 dddq[2][2][3]= 2.0*q[3];
335 if(abs(eigenvals[0]-eigenvals[k+1])<1.e-8){
336 log->
printf(
" FOUND DEGENERACY IN RMSD_ESS ROUTINE \n");
346 gamma[i][j][k] += dddq[i][j][l]*eigenvecs(k+1,l)/(eigenvals[0]-eigenvals[k+1]);
361 vector<double> dd_dr_temp;dd_dr_temp.resize(natoms);
363 vector<Vector> derr_dr1;
364 derr_dr1.resize(natoms);
365 vector<Vector> derr_dr0;
366 derr_dr0.resize(natoms);
367 vector<Vector> array_3_n;
368 array_3_n.resize(natoms);
376 for(iii=0;iii<alignmap.size();iii++){
379 tmp1=sqrt(
align[i]/totalign);
387 dm_r1 [0][0][0]=(rr1[0]-rr0[0]);
388 dm_r1 [0][0][1]=(rr1[1]-rr0[1]);
389 dm_r1 [0][0][2]=(rr1[2]-rr0[2]);
392 dm_r1 [0][1][1]= rr0[2];
393 dm_r1 [0][1][2]=-rr0[1];
395 dm_r1 [0][2][0]=-rr0[2];
397 dm_r1 [0][2][2]= rr0[0];
399 dm_r1 [0][3][0]= rr0[1];
400 dm_r1 [0][3][1]=-rr0[0];
403 dm_r1 [1][1][0]=(rr1[0]-rr0[0]);
404 dm_r1 [1][1][1]=(rr1[1]+rr0[1]);
405 dm_r1 [1][1][2]=(rr1[2]+rr0[2]);
407 dm_r1 [1][2][0]=-rr0[1];
408 dm_r1 [1][2][1]=-rr0[0];
411 dm_r1 [1][3][0]=-rr0[2];
413 dm_r1 [1][3][2]=-rr0[0];
415 dm_r1 [2][2][0]=(rr1[0]+rr0[0]);
416 dm_r1 [2][2][1]=(rr1[1]-rr0[1]);
417 dm_r1 [2][2][2]=(rr1[2]+rr0[2]);
420 dm_r1 [2][3][1]=-rr0[2];
421 dm_r1 [2][3][2]=-rr0[1];
423 dm_r1 [3][3][0]=(rr1[0]+rr0[0]);
424 dm_r1 [3][3][1]=(rr1[1]+rr0[1]);
425 dm_r1 [3][3][2]=(rr1[2]-rr0[2]);
429 dm_r0 [0][0][0]=-(rr1[0]-rr0[0]);
430 dm_r0 [0][0][1]=-(rr1[1]-rr0[1]);
431 dm_r0 [0][0][2]=-(rr1[2]-rr0[2]);
434 dm_r0 [0][1][1]=-rr1[2];
435 dm_r0 [0][1][2]=rr1[1];
437 dm_r0 [0][2][0]= rr1[2];
439 dm_r0 [0][2][2]=-rr1[0];
441 dm_r0 [0][3][0]=-rr1[1] ;
442 dm_r0 [0][3][1]= rr1[0];
445 dm_r0 [1][1][0]=-(rr1[0]-rr0[0]);
446 dm_r0 [1][1][1]=(rr1[1]+rr0[1]);
447 dm_r0 [1][1][2]=(rr1[2]+rr0[2]);
449 dm_r0 [1][2][0]=-rr1[1];
450 dm_r0 [1][2][1]=-rr1[0];
453 dm_r0 [1][3][0]=-rr1[2];
455 dm_r0 [1][3][2]=-rr1[0];
457 dm_r0 [2][2][0]=(rr1[0]+rr0[0]);
458 dm_r0 [2][2][1]=-(rr1[1]-rr0[1]);
459 dm_r0 [2][2][2]=(rr1[2]+rr0[2]);
462 dm_r0 [2][3][1]=-rr1[2];
463 dm_r0 [2][3][2]=-rr1[1];
465 dm_r0 [3][3][0]=(rr1[0]+rr0[0]);
466 dm_r0 [3][3][1]=(rr1[1]+rr0[1]);
467 dm_r0 [3][3][2]=-(rr1[2]-rr0[2]);
472 dm_r1[1][0]=dm_r1[0][1];
473 dm_r1[2][0]=dm_r1[0][2];
474 dm_r1[3][0]=dm_r1[0][3];
475 dm_r1[2][1]=dm_r1[1][2];
476 dm_r1[3][1]=dm_r1[1][3];
477 dm_r1[3][2]=dm_r1[2][3];
479 dm_r0[1][0]=dm_r0[0][1];
480 dm_r0[2][0]=dm_r0[0][2];
481 dm_r0[3][0]=dm_r0[0][3];
482 dm_r0[2][1]=dm_r0[1][2];
483 dm_r0[3][1]=dm_r0[1][3];
484 dm_r0[3][2]=dm_r0[2][3];
501 derr_dr1[i]+=(q[k]*q[l])*dm_r1[l][k];
502 derr_dr0[i]+=(q[k]*q[l])*dm_r0[l][k];
503 for(mm=0;mm<3;mm++)
for(j=0;j<3;j++){
504 pi0[mm][j]+=eigenvecs(mm+1,k)*dm_r0[l][k][j]*q[l];
505 pi1[mm][j]+=eigenvecs(mm+1,k)*dm_r1[l][k][j]*q[l];
519 int ind=j*3*3*natoms+k*3*natoms+l*natoms+i;
523 dmatdp1[ind]+=gamma[j][k][ii]*pi1[ii][l];
524 dmatdp0[ind]+=gamma[j][k][ii]*pi0[ii][l];
544 bool comcorr_r1=
true;
547 for(k=0;k<alignmap.size();k++){
549 tmp1=sqrt(
align[i]/totalign);
550 array_3_n[i]=tmp1*derr_dr1[i];
552 for(jj=0;jj<alignmap.size();jj++){
554 array_3_n[i]-=tmp1*(
align[j]/totalign)*derr_dr1[j];
558 for(k=0;k<alignmap.size();k++){
560 derr_dr1[i]=array_3_n[i];
565 bool do_comcorr_r0=
true;
570 for(k=0;k<alignmap.size();k++){
572 tmp1=sqrt(
align[i]/totalign);
573 array_3_n[i]=tmp1*derr_dr0[i];
575 for(jj=0;jj<alignmap.size();jj++){
577 array_3_n[i]-=tmp1*(
align[j]/totalign)*derr_dr0[j];
581 for(k=0;k<alignmap.size();k++){
583 derr_dr0[i]=array_3_n[i];
590 bool do_der_rotmat=
true;
592 if(do_der_r1 && do_der_rotmat){
596 for(ll=0;ll<alignmap.size();ll++){
598 int ind=i*3*3*natoms+j*3*natoms+k*natoms+l;
599 tmp1=sqrt(
align[l]/totalign);
600 dd_dr_temp[l]=tmp1*
dmatdp1[ind];
602 for(nn=0;nn<alignmap.size();nn++){
604 dd_dr_temp[l]-=dmatdp1[ind-l+
n]*tmp1*
align[
n]/totalign;
609 for(ll=0;ll<alignmap.size();ll++){
611 int ind=i*3*3*natoms+j*3*natoms+k*natoms+l;
621 if(do_der_r0 && do_der_rotmat){
625 for(ll=0;ll<alignmap.size();ll++){
627 int ind=i*3*3*natoms+j*3*natoms+k*natoms+l;
628 tmp1=sqrt(
align[l]/totalign);
629 dd_dr_temp[l]=tmp1*
dmatdp0[ind];
631 for(nn=0;nn<alignmap.size();nn++){
633 dd_dr_temp[l]-=dmatdp0[ind-l+
n]*tmp1*
align[
n]/totalign;
637 for(ll=0;ll<alignmap.size();ll++){
639 int ind=i*3*3*natoms+j*3*natoms+k*natoms+l;
648 bool do_p1rotated=
true;
660 for(i=0;i<natoms;i++){
666 for(i=0;i<natoms;i++){
671 for(i=0;i<natoms;i++){
683 bool do_p0rotated=
true;
690 log->
printf(
"P0-RESET AND INVERSE ROTATED\n");
691 for(i=0;i<natoms;i++){
696 for(i=0;i<natoms;i++){
714 for(ii=0;ii<alignmap.size();ii++){
739 log->
printf(
"Entering rmsd finite difference test system for kearsley\n");
740 log->
printf(
"-------------------------------------------\n");
741 log->
printf(
"TEST1: derivative of the value (derr_dr0/derr_dr1)\n");
744 double step=1.e-6,olderr,
delta;
747 vector<double> align1;
748 align1.resize(
p0.size());
750 for (i=0;i<
p0.size();i++){
757 }
else{align1[i]=0.;};
763 log->
printf(
"INITIAL ERROR VALUE: %e\n",olderr);
770 for(
unsigned j=0;j<3;j++){
771 for(
unsigned i=0;i<
derrdp1.size();i++){
773 delta=(rnd.
RandU01()-0.5)*2*step;
793 for(
unsigned j=0;j<3;j++){
794 for(
unsigned i=0;i<
derrdp0.size();i++){
796 delta=(rnd.
RandU01()-0.5)*2*step;
818 for(i=0;i<
p0.size();i++){
820 delta=(rnd.
RandU01()-0.5)*2*step;
826 int ind=l*3*3*
p0.size()+m*3*
p0.size()+j*
p0.size()+i;
829 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;
832 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;
835 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;
846 for(i=0;i<
p1.size();i++){
848 delta=(rnd.
RandU01()-0.5)*2*step;
854 int ind=l*3*3*
p1.size()+m*3*
p1.size()+j*
p1.size()+i;
858 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;
861 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;
864 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;
void zero()
set it to zero
std::vector< Vector > p1rotated
position rotated: p1
std::vector< double > dmatdp1
TensorGeneric< 3, 3 > inverse(const TensorGeneric< 3, 3 > &t)
Class implementing fixed size matrices of doubles.
TensorGeneric< n, l > matmul(const TensorGeneric< n, m > &a, const TensorGeneric< m, l > &b)
Class implementing fixed size vectors of doubles.
double err
error: the distance between two frames (might be rmsd/msd. See below)
Class containing the log stream.
std::vector< Vector > p1reset
position resetted wrt coms p1
void zero()
set it to zero
std::vector< Vector > derrdp1
derivatives: derivative of the error respect p1
std::vector< Vector > p0rotated
position rotated: p0
static TensorGeneric< n, n > identity()
return an identity tensor
Log * log
general log reference that needs to be initialized when constructed
void assignP0(const std::vector< Vector > &p0)
switch the assignment of the structure p0 (e.g. at each md step)
double calculate(bool rmsd)
std::vector< Vector > diff1on0
displacement: the vector that goes from the p1 onto p0 (via inverse rotation)
std::vector< Vector > p0
position of atoms (first frame. In md is the running frame)
std::vector< double > align
alignment weight: the rmsd/msd that it provides is only based on this scalar
int printf(const char *fmt,...)
Formatted output with explicit format - a la printf.
VectorGeneric< n > delta(const VectorGeneric< n > &v1, const VectorGeneric< n > &v2)
std::vector< Vector > p0reset
position resetted wrt coms p0
Vector com0
center of mass of p0
void assignP1(const std::vector< Vector > &p1)
derivatives: derivative of the error respect p1
int diagMat(const Matrix< T > &A, std::vector< double > &eigenvals, Matrix< double > &eigenvecs)
double modulo2(const VectorGeneric< n > &v)
std::vector< Vector > diff0on1
displacement: the vector that goes from the p0 onto p1
Vector com1
center of mass of p1
void assignAlign(const std::vector< double > &align)
transfer the alignment vector
std::vector< double > dmatdp0
derivative of the rotation matrix note the dimension 3x3 x 3 x N
Tensor rotmat0on1
rotation matrices p0 on p1 and reverse (p1 over p0)
std::vector< Vector > p1
position of atoms (second frame. In md is the reference frame)
std::vector< Vector > derrdp0
derivatives: derivative of the error respect p0
void finiteDifferenceInterface(bool rmsd)
finite differences of all the relevant quantities: takes a bool which decides if giving back rmsd or ...