1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
34 * GROningen Mixture of Alchemy and Childrens' Stories
50 #include "mtop_util.h"
52 void init_orires(FILE *fplog
,const gmx_mtop_t
*mtop
,
55 const gmx_multisim_t
*ms
,t_oriresdata
*od
,
58 int i
,j
,d
,ex
,nmol
,nr
,*nr_ex
;
61 gmx_mtop_ilistloop_t iloop
;
63 gmx_mtop_atomloop_all_t aloop
;
66 od
->fc
= ir
->orires_fc
;
70 od
->nr
= gmx_mtop_ftype_count(mtop
,F_ORIRES
);
78 iloop
= gmx_mtop_ilistloop_init(mtop
);
79 while (gmx_mtop_ilistloop_next(iloop
,&il
,&nmol
))
81 for(i
=0; i
<il
[F_ORIRES
].nr
; i
+=3)
83 ex
= mtop
->ffparams
.iparams
[il
[F_ORIRES
].iatoms
[i
]].orires
.ex
;
87 for(j
=od
->nex
; j
<ex
+1; j
++)
97 /* When not doing time averaging, the instaneous and time averaged data
98 * are indentical and the pointers can point to the same memory.
100 snew(od
->Dinsl
,od
->nr
);
103 snew(od
->Dins
,od
->nr
);
107 od
->Dins
= od
->Dinsl
;
110 if (ir
->orires_tau
== 0)
118 snew(od
->Dtav
,od
->nr
);
119 od
->edt
= exp(-ir
->delta_t
/ir
->orires_tau
);
120 od
->edt_1
= 1.0 - od
->edt
;
122 /* Extend the state with the orires history */
123 state
->flags
|= (1<<estORIRE_INITF
);
124 state
->hist
.orire_initf
= 1;
125 state
->flags
|= (1<<estORIRE_DTAV
);
126 state
->hist
.norire_Dtav
= od
->nr
*5;
127 snew(state
->hist
.orire_Dtav
,state
->hist
.norire_Dtav
);
130 snew(od
->oinsl
,od
->nr
);
133 snew(od
->oins
,od
->nr
);
137 od
->oins
= od
->oinsl
;
139 if (ir
->orires_tau
== 0) {
144 snew(od
->otav
,od
->nr
);
146 snew(od
->tmp
,od
->nex
);
147 snew(od
->TMP
,od
->nex
);
148 for(ex
=0; ex
<od
->nex
; ex
++)
153 snew(od
->TMP
[ex
][i
],5);
158 for(i
=0; i
<mtop
->natoms
; i
++)
160 if (ggrpnr(&mtop
->groups
,egcORFIT
,i
) == 0)
165 snew(od
->mref
,od
->nref
);
166 snew(od
->xref
,od
->nref
);
167 snew(od
->xtmp
,od
->nref
);
169 snew(od
->eig
,od
->nex
*12);
171 /* Determine the reference structure on the master node.
172 * Copy it to the other nodes after checking multi compatibility,
173 * so we are sure the subsystems match before copying.
178 aloop
= gmx_mtop_atomloop_all_init(mtop
);
179 while(gmx_mtop_atomloop_all_next(aloop
,&i
,&atom
))
181 if (mtop
->groups
.grpnr
[egcORFIT
] == NULL
||
182 mtop
->groups
.grpnr
[egcORFIT
][i
] == 0)
184 /* Not correct for free-energy with changing masses */
185 od
->mref
[j
] = atom
->m
;
186 if (ms
==NULL
|| MASTERSIM(ms
))
188 copy_rvec(xref
[i
],od
->xref
[j
]);
191 com
[d
] += od
->mref
[j
]*xref
[i
][d
];
198 svmul(1.0/mtot
,com
,com
);
199 if (ms
==NULL
|| MASTERSIM(ms
))
201 for(j
=0; j
<od
->nref
; j
++)
203 rvec_dec(od
->xref
[j
],com
);
207 fprintf(fplog
,"Found %d orientation experiments\n",od
->nex
);
208 for(i
=0; i
<od
->nex
; i
++)
210 fprintf(fplog
," experiment %d has %d restraints\n",i
+1,nr_ex
[i
]);
215 fprintf(fplog
," the fit group consists of %d atoms and has total mass %g\n",
220 fprintf(fplog
," the orientation restraints are ensemble averaged over %d systems\n",ms
->nsim
);
222 check_multi_int(fplog
,ms
,od
->nr
,
223 "the number of orientation restraints");
224 check_multi_int(fplog
,ms
,od
->nref
,
225 "the number of fit atoms for orientation restraining");
226 check_multi_int(fplog
,ms
,ir
->nsteps
,"nsteps");
227 /* Copy the reference coordinates from the master to the other nodes */
228 gmx_sum_sim(DIM
*od
->nref
,od
->xref
[0],ms
);
231 please_cite(fplog
,"Hess2003");
234 void diagonalize_orires_tensors(t_oriresdata
*od
)
236 int ex
,i
,j
,nrot
,ord
[DIM
],t
;
238 static double **M
=NULL
,*eig
,**v
;
255 for(ex
=0; ex
<od
->nex
; ex
++)
257 /* Rotate the S tensor back to the reference frame */
258 mmul(od
->R
,od
->S
[ex
],TMP
);
268 jacobi(M
,DIM
,eig
,v
,&nrot
);
276 for(j
=i
+1; j
<DIM
; j
++)
278 if (sqr(eig
[ord
[j
]]) > sqr(eig
[ord
[i
]]))
289 od
->eig
[ex
*12 + i
] = eig
[ord
[i
]];
295 od
->eig
[ex
*12 + 3 + 3*i
+ j
] = v
[j
][ord
[i
]];
301 void print_orires_log(FILE *log
,t_oriresdata
*od
)
306 diagonalize_orires_tensors(od
);
308 for(ex
=0; ex
<od
->nex
; ex
++)
310 eig
= od
->eig
+ ex
*12;
311 fprintf(log
," Orientation experiment %d:\n",ex
+1);
312 fprintf(log
," order parameter: %g\n",eig
[0]);
315 fprintf(log
," eig: %6.3f %6.3f %6.3f %6.3f\n",
316 (eig
[0] != 0) ? eig
[i
]/eig
[0] : eig
[i
],
325 real
calc_orires_dev(const gmx_multisim_t
*ms
,
326 int nfa
,const t_iatom forceatoms
[],const t_iparams ip
[],
327 const t_mdatoms
*md
,const rvec x
[],const t_pbc
*pbc
,
328 t_fcdata
*fcd
,history_t
*hist
)
330 int fa
,d
,i
,j
,type
,ex
,nref
;
331 real edt
,edt_1
,invn
,pfac
,r2
,invr
,corrfac
,weight
,wsv2
,sw
,dev
;
333 rvec5
*Dinsl
,*Dins
,*Dtav
,*rhs
;
336 rvec
*xref
,*xtmp
,com
,r_unrot
,r
;
339 const real two_thr
=2.0/3.0;
345 /* This means that this is not the master node */
346 gmx_fatal(FARGS
,"Orientation restraints are only supported on the master node, use less processors");
349 bTAV
= (od
->edt
!= 0);
365 od
->exp_min_t_tau
= hist
->orire_initf
*edt
;
367 /* Correction factor to correct for the lack of history
370 corrfac
= 1.0/(1.0 - od
->exp_min_t_tau
);
389 for(i
=0; i
<md
->nr
; i
++)
391 if (md
->cORF
[i
] == 0)
393 copy_rvec(x
[i
],xtmp
[j
]);
394 mref
[j
] = md
->massT
[i
];
397 com
[d
] += mref
[j
]*xref
[j
][d
];
403 svmul(1.0/mtot
,com
,com
);
404 for(j
=0; j
<nref
; j
++)
406 rvec_dec(xtmp
[j
],com
);
408 /* Calculate the rotation matrix to rotate x to the reference orientation */
409 calc_fit_R(DIM
,nref
,mref
,xref
,xtmp
,R
);
413 for(fa
=0; fa
<nfa
; fa
+=3)
415 type
= forceatoms
[fa
];
418 pbc_dx_aiuc(pbc
,x
[forceatoms
[fa
+1]],x
[forceatoms
[fa
+2]],r_unrot
);
422 rvec_sub(x
[forceatoms
[fa
+1]],x
[forceatoms
[fa
+2]],r_unrot
);
426 invr
= gmx_invsqrt(r2
);
427 /* Calculate the prefactor for the D tensor, this includes the factor 3! */
428 pfac
= ip
[type
].orires
.c
*invr
*invr
*3;
429 for(i
=0; i
<ip
[type
].orires
.power
; i
++)
433 Dinsl
[d
][0] = pfac
*(2*r
[0]*r
[0] + r
[1]*r
[1] - r2
);
434 Dinsl
[d
][1] = pfac
*(2*r
[0]*r
[1]);
435 Dinsl
[d
][2] = pfac
*(2*r
[0]*r
[2]);
436 Dinsl
[d
][3] = pfac
*(2*r
[1]*r
[1] + r
[0]*r
[0] - r2
);
437 Dinsl
[d
][4] = pfac
*(2*r
[1]*r
[2]);
443 Dins
[d
][i
] = Dinsl
[d
][i
]*invn
;
452 gmx_sum_sim(5*od
->nr
,Dins
[0],ms
);
455 /* Calculate the order tensor S for each experiment via optimization */
456 for(ex
=0; ex
<od
->nex
; ex
++)
468 for(fa
=0; fa
<nfa
; fa
+=3)
472 /* Here we update Dtav in t_fcdata using the data in history_t.
473 * Thus the results stay correct when this routine
474 * is called multiple times.
478 Dtav
[d
][i
] = edt
*hist
->orire_Dtav
[d
*5+i
] + edt_1
*Dins
[d
][i
];
482 type
= forceatoms
[fa
];
483 ex
= ip
[type
].orires
.ex
;
484 weight
= ip
[type
].orires
.kfac
;
485 /* Calculate the vector rhs and half the matrix T for the 5 equations */
487 rhs
[ex
][i
] += Dtav
[d
][i
]*ip
[type
].orires
.obs
*weight
;
490 T
[ex
][i
][j
] += Dtav
[d
][i
]*Dtav
[d
][j
]*weight
;
495 /* Now we have all the data we can calculate S */
496 for(ex
=0; ex
<od
->nex
; ex
++)
498 /* Correct corrfac and copy one half of T to the other half */
501 rhs
[ex
][i
] *= corrfac
;
502 T
[ex
][i
][i
] *= sqr(corrfac
);
505 T
[ex
][i
][j
] *= sqr(corrfac
);
506 T
[ex
][j
][i
] = T
[ex
][i
][j
];
509 m_inv_gen(T
[ex
],5,T
[ex
]);
510 /* Calculate the orientation tensor S for this experiment */
518 S
[ex
][0][0] += 1.5*T
[ex
][0][i
]*rhs
[ex
][i
];
519 S
[ex
][0][1] += 1.5*T
[ex
][1][i
]*rhs
[ex
][i
];
520 S
[ex
][0][2] += 1.5*T
[ex
][2][i
]*rhs
[ex
][i
];
521 S
[ex
][1][1] += 1.5*T
[ex
][3][i
]*rhs
[ex
][i
];
522 S
[ex
][1][2] += 1.5*T
[ex
][4][i
]*rhs
[ex
][i
];
524 S
[ex
][1][0] = S
[ex
][0][1];
525 S
[ex
][2][0] = S
[ex
][0][2];
526 S
[ex
][2][1] = S
[ex
][1][2];
527 S
[ex
][2][2] = -S
[ex
][0][0] - S
[ex
][1][1];
534 for(fa
=0; fa
<nfa
; fa
+=3)
536 type
= forceatoms
[fa
];
537 ex
= ip
[type
].orires
.ex
;
539 od
->otav
[d
] = two_thr
*
540 corrfac
*(S
[ex
][0][0]*Dtav
[d
][0] + S
[ex
][0][1]*Dtav
[d
][1] +
541 S
[ex
][0][2]*Dtav
[d
][2] + S
[ex
][1][1]*Dtav
[d
][3] +
542 S
[ex
][1][2]*Dtav
[d
][4]);
545 od
->oins
[d
] = two_thr
*(S
[ex
][0][0]*Dins
[d
][0] + S
[ex
][0][1]*Dins
[d
][1] +
546 S
[ex
][0][2]*Dins
[d
][2] + S
[ex
][1][1]*Dins
[d
][3] +
547 S
[ex
][1][2]*Dins
[d
][4]);
551 /* When ensemble averaging is used recalculate the local orientation
552 * for output to the energy file.
554 od
->oinsl
[d
] = two_thr
*
555 (S
[ex
][0][0]*Dinsl
[d
][0] + S
[ex
][0][1]*Dinsl
[d
][1] +
556 S
[ex
][0][2]*Dinsl
[d
][2] + S
[ex
][1][1]*Dinsl
[d
][3] +
557 S
[ex
][1][2]*Dinsl
[d
][4]);
560 dev
= od
->otav
[d
] - ip
[type
].orires
.obs
;
562 wsv2
+= ip
[type
].orires
.kfac
*sqr(dev
);
563 sw
+= ip
[type
].orires
.kfac
;
567 od
->rmsdev
= sqrt(wsv2
/sw
);
569 /* Rotate the S matrices back, so we get the correct grad(tr(S D)) */
570 for(ex
=0; ex
<od
->nex
; ex
++)
578 /* Approx. 120*nfa/3 flops */
581 real
orires(int nfa
,const t_iatom forceatoms
[],const t_iparams ip
[],
582 const rvec x
[],rvec f
[],rvec fshift
[],
583 const t_pbc
*pbc
,const t_graph
*g
,
584 real lambda
,real
*dvdlambda
,
585 const t_mdatoms
*md
,t_fcdata
*fcd
,
586 int *global_atom_index
)
589 int fa
,d
,i
,type
,ex
,power
,ki
=CENTRAL
;
591 real r2
,invr
,invr2
,fc
,smooth_fc
,dev
,devins
,pfac
;
594 const t_oriresdata
*od
;
602 bTAV
= (od
->edt
!= 0);
607 /* Smoothly switch on the restraining when time averaging is used */
608 smooth_fc
*= (1.0 - od
->exp_min_t_tau
);
612 for(fa
=0; fa
<nfa
; fa
+=3)
614 type
= forceatoms
[fa
];
615 ai
= forceatoms
[fa
+1];
616 aj
= forceatoms
[fa
+2];
619 ki
= pbc_dx_aiuc(pbc
,x
[ai
],x
[aj
],r
);
623 rvec_sub(x
[ai
],x
[aj
],r
);
626 invr
= gmx_invsqrt(r2
);
628 ex
= ip
[type
].orires
.ex
;
629 power
= ip
[type
].orires
.power
;
630 fc
= smooth_fc
*ip
[type
].orires
.kfac
;
631 dev
= od
->otav
[d
] - ip
[type
].orires
.obs
;
634 * there is no real potential when time averaging is applied
636 vtot
+= 0.5*fc
*sqr(dev
);
640 /* Calculate the force as the sqrt of tav times instantaneous */
641 devins
= od
->oins
[d
] - ip
[type
].orires
.obs
;
648 dev
= sqrt(dev
*devins
);
656 pfac
= fc
*ip
[type
].orires
.c
*invr2
;
657 for(i
=0; i
<power
; i
++)
661 mvmul(od
->S
[ex
],r
,Sr
);
665 -pfac
*dev
*(4*Sr
[i
] - 2*(2+power
)*invr2
*iprod(Sr
,r
)*r
[i
]);
670 ivec_sub(SHIFT_IVEC(g
,ai
),SHIFT_IVEC(g
,aj
),dt
);
678 fshift
[ki
][i
] += fij
[i
];
679 fshift
[CENTRAL
][i
] -= fij
[i
];
687 /* Approx. 80*nfa/3 flops */
690 void update_orires_history(t_fcdata
*fcd
,history_t
*hist
)
698 /* Copy the new time averages that have been calculated
699 * in calc_orires_dev.
701 hist
->orire_initf
= od
->exp_min_t_tau
;
702 for(pair
=0; pair
<od
->nr
; pair
++)
706 hist
->orire_Dtav
[pair
*5+i
] = od
->Dtav
[pair
][i
];