3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * GROwing Monsters And Cloning Shrimps
52 #include "mtop_util.h"
54 /* Routines to send/recieve coordinates and force
55 * of constructing atoms.
58 static void move_construct_x(t_comm_vsites
*vsitecomm
, rvec x
[], t_commrec
*cr
)
64 sendbuf
= vsitecomm
->send_buf
;
65 recvbuf
= vsitecomm
->recv_buf
;
68 /* Prepare pulse left by copying to send buffer */
69 for(i
=0;i
<vsitecomm
->left_export_nconstruct
;i
++)
71 ia
= vsitecomm
->left_export_construct
[i
];
72 copy_rvec(x
[ia
],sendbuf
[i
]);
75 /* Pulse coordinates left */
76 gmx_tx_rx_real(cr
,GMX_LEFT
,(real
*)sendbuf
,3*vsitecomm
->left_export_nconstruct
,GMX_RIGHT
,(real
*)recvbuf
,3*vsitecomm
->right_import_nconstruct
);
78 /* Copy from receive buffer to coordinate array */
79 for(i
=0;i
<vsitecomm
->right_import_nconstruct
;i
++)
81 ia
= vsitecomm
->right_import_construct
[i
];
82 copy_rvec(recvbuf
[i
],x
[ia
]);
85 /* Prepare pulse right by copying to send buffer */
86 for(i
=0;i
<vsitecomm
->right_export_nconstruct
;i
++)
88 ia
= vsitecomm
->right_export_construct
[i
];
89 copy_rvec(x
[ia
],sendbuf
[i
]);
92 /* Pulse coordinates right */
93 gmx_tx_rx_real(cr
,GMX_RIGHT
,(real
*)sendbuf
,3*vsitecomm
->right_export_nconstruct
,GMX_LEFT
,(real
*)recvbuf
,3*vsitecomm
->left_import_nconstruct
);
95 /* Copy from receive buffer to coordinate array */
96 for(i
=0;i
<vsitecomm
->left_import_nconstruct
;i
++)
98 ia
= vsitecomm
->left_import_construct
[i
];
99 copy_rvec(recvbuf
[i
],x
[ia
]);
104 static void move_construct_f(t_comm_vsites
*vsitecomm
, rvec f
[], t_commrec
*cr
)
110 sendbuf
= vsitecomm
->send_buf
;
111 recvbuf
= vsitecomm
->recv_buf
;
113 /* Prepare pulse right by copying to send buffer */
114 for(i
=0;i
<vsitecomm
->right_import_nconstruct
;i
++)
116 ia
= vsitecomm
->right_import_construct
[i
];
117 copy_rvec(f
[ia
],sendbuf
[i
]);
118 clear_rvec(f
[ia
]); /* Zero it here after moving, just to simplify debug book-keeping... */
121 /* Pulse forces right */
122 gmx_tx_rx_real(cr
,GMX_RIGHT
,(real
*)sendbuf
,3*vsitecomm
->right_import_nconstruct
,GMX_LEFT
,(real
*)recvbuf
,3*vsitecomm
->left_export_nconstruct
);
124 /* Copy from receive buffer to coordinate array */
125 for(i
=0;i
<vsitecomm
->left_export_nconstruct
;i
++)
127 ia
= vsitecomm
->left_export_construct
[i
];
128 rvec_inc(f
[ia
],recvbuf
[i
]);
131 /* Prepare pulse left by copying to send buffer */
132 for(i
=0;i
<vsitecomm
->left_import_nconstruct
;i
++)
134 ia
= vsitecomm
->left_import_construct
[i
];
135 copy_rvec(f
[ia
],sendbuf
[i
]);
136 clear_rvec(f
[ia
]); /* Zero it here after moving, just to simplify debug book-keeping... */
139 /* Pulse coordinates left */
140 gmx_tx_rx_real(cr
,GMX_LEFT
,(real
*)sendbuf
,3*vsitecomm
->left_import_nconstruct
,GMX_RIGHT
,(real
*)recvbuf
,3*vsitecomm
->right_export_nconstruct
);
142 /* Copy from receive buffer to coordinate array */
143 for(i
=0;i
<vsitecomm
->right_export_nconstruct
;i
++)
145 ia
= vsitecomm
->right_export_construct
[i
];
146 rvec_inc(f
[ia
],recvbuf
[i
]);
149 /* All forces are now on the home processors */
154 pd_clear_nonlocal_constructs(t_comm_vsites
*vsitecomm
, rvec f
[])
158 for(i
=0;i
<vsitecomm
->left_import_nconstruct
;i
++)
160 ia
= vsitecomm
->left_import_construct
[i
];
163 for(i
=0;i
<vsitecomm
->right_import_nconstruct
;i
++)
165 ia
= vsitecomm
->right_import_construct
[i
];
172 static int pbc_rvec_sub(const t_pbc
*pbc
,const rvec xi
,const rvec xj
,rvec dx
)
175 return pbc_dx_aiuc(pbc
,xi
,xj
,dx
);
183 /* Vsite construction routines */
185 static void constr_vsite2(rvec xi
,rvec xj
,rvec x
,real a
,t_pbc
*pbc
)
194 pbc_dx_aiuc(pbc
,xj
,xi
,dx
);
195 x
[XX
] = xi
[XX
] + a
*dx
[XX
];
196 x
[YY
] = xi
[YY
] + a
*dx
[YY
];
197 x
[ZZ
] = xi
[ZZ
] + a
*dx
[ZZ
];
199 x
[XX
] = b
*xi
[XX
] + a
*xj
[XX
];
200 x
[YY
] = b
*xi
[YY
] + a
*xj
[YY
];
201 x
[ZZ
] = b
*xi
[ZZ
] + a
*xj
[ZZ
];
205 /* TOTAL: 10 flops */
208 static void constr_vsite3(rvec xi
,rvec xj
,rvec xk
,rvec x
,real a
,real b
,
218 pbc_dx_aiuc(pbc
,xj
,xi
,dxj
);
219 pbc_dx_aiuc(pbc
,xk
,xi
,dxk
);
220 x
[XX
] = xi
[XX
] + a
*dxj
[XX
] + b
*dxk
[XX
];
221 x
[YY
] = xi
[YY
] + a
*dxj
[YY
] + b
*dxk
[YY
];
222 x
[ZZ
] = xi
[ZZ
] + a
*dxj
[ZZ
] + b
*dxk
[ZZ
];
224 x
[XX
] = c
*xi
[XX
] + a
*xj
[XX
] + b
*xk
[XX
];
225 x
[YY
] = c
*xi
[YY
] + a
*xj
[YY
] + b
*xk
[YY
];
226 x
[ZZ
] = c
*xi
[ZZ
] + a
*xj
[ZZ
] + b
*xk
[ZZ
];
230 /* TOTAL: 17 flops */
233 static void constr_vsite3FD(rvec xi
,rvec xj
,rvec xk
,rvec x
,real a
,real b
,
239 pbc_rvec_sub(pbc
,xj
,xi
,xij
);
240 pbc_rvec_sub(pbc
,xk
,xj
,xjk
);
243 /* temp goes from i to a point on the line jk */
244 temp
[XX
] = xij
[XX
] + a
*xjk
[XX
];
245 temp
[YY
] = xij
[YY
] + a
*xjk
[YY
];
246 temp
[ZZ
] = xij
[ZZ
] + a
*xjk
[ZZ
];
249 c
=b
*gmx_invsqrt(iprod(temp
,temp
));
252 x
[XX
] = xi
[XX
] + c
*temp
[XX
];
253 x
[YY
] = xi
[YY
] + c
*temp
[YY
];
254 x
[ZZ
] = xi
[ZZ
] + c
*temp
[ZZ
];
257 /* TOTAL: 34 flops */
260 static void constr_vsite3FAD(rvec xi
,rvec xj
,rvec xk
,rvec x
,real a
,real b
, t_pbc
*pbc
)
263 real a1
,b1
,c1
,invdij
;
265 pbc_rvec_sub(pbc
,xj
,xi
,xij
);
266 pbc_rvec_sub(pbc
,xk
,xj
,xjk
);
269 invdij
= gmx_invsqrt(iprod(xij
,xij
));
270 c1
= invdij
* invdij
* iprod(xij
,xjk
);
271 xp
[XX
] = xjk
[XX
] - c1
*xij
[XX
];
272 xp
[YY
] = xjk
[YY
] - c1
*xij
[YY
];
273 xp
[ZZ
] = xjk
[ZZ
] - c1
*xij
[ZZ
];
275 b1
= b
*gmx_invsqrt(iprod(xp
,xp
));
278 x
[XX
] = xi
[XX
] + a1
*xij
[XX
] + b1
*xp
[XX
];
279 x
[YY
] = xi
[YY
] + a1
*xij
[YY
] + b1
*xp
[YY
];
280 x
[ZZ
] = xi
[ZZ
] + a1
*xij
[ZZ
] + b1
*xp
[ZZ
];
283 /* TOTAL: 63 flops */
286 static void constr_vsite3OUT(rvec xi
,rvec xj
,rvec xk
,rvec x
,
287 real a
,real b
,real c
,t_pbc
*pbc
)
291 pbc_rvec_sub(pbc
,xj
,xi
,xij
);
292 pbc_rvec_sub(pbc
,xk
,xi
,xik
);
296 x
[XX
] = xi
[XX
] + a
*xij
[XX
] + b
*xik
[XX
] + c
*temp
[XX
];
297 x
[YY
] = xi
[YY
] + a
*xij
[YY
] + b
*xik
[YY
] + c
*temp
[YY
];
298 x
[ZZ
] = xi
[ZZ
] + a
*xij
[ZZ
] + b
*xik
[ZZ
] + c
*temp
[ZZ
];
301 /* TOTAL: 33 flops */
304 static void constr_vsite4FD(rvec xi
,rvec xj
,rvec xk
,rvec xl
,rvec x
,
305 real a
,real b
,real c
,t_pbc
*pbc
)
307 rvec xij
,xjk
,xjl
,temp
;
310 pbc_rvec_sub(pbc
,xj
,xi
,xij
);
311 pbc_rvec_sub(pbc
,xk
,xj
,xjk
);
312 pbc_rvec_sub(pbc
,xl
,xj
,xjl
);
315 /* temp goes from i to a point on the plane jkl */
316 temp
[XX
] = xij
[XX
] + a
*xjk
[XX
] + b
*xjl
[XX
];
317 temp
[YY
] = xij
[YY
] + a
*xjk
[YY
] + b
*xjl
[YY
];
318 temp
[ZZ
] = xij
[ZZ
] + a
*xjk
[ZZ
] + b
*xjl
[ZZ
];
321 d
=c
*gmx_invsqrt(iprod(temp
,temp
));
324 x
[XX
] = xi
[XX
] + d
*temp
[XX
];
325 x
[YY
] = xi
[YY
] + d
*temp
[YY
];
326 x
[ZZ
] = xi
[ZZ
] + d
*temp
[ZZ
];
329 /* TOTAL: 43 flops */
333 static void constr_vsite4FDN(rvec xi
,rvec xj
,rvec xk
,rvec xl
,rvec x
,
334 real a
,real b
,real c
,t_pbc
*pbc
)
336 rvec xij
,xik
,xil
,ra
,rb
,rja
,rjb
,rm
;
339 pbc_rvec_sub(pbc
,xj
,xi
,xij
);
340 pbc_rvec_sub(pbc
,xk
,xi
,xik
);
341 pbc_rvec_sub(pbc
,xl
,xi
,xil
);
354 rvec_sub(ra
,xij
,rja
);
355 rvec_sub(rb
,xij
,rjb
);
361 d
=c
*gmx_invsqrt(norm2(rm
));
364 x
[XX
] = xi
[XX
] + d
*rm
[XX
];
365 x
[YY
] = xi
[YY
] + d
*rm
[YY
];
366 x
[ZZ
] = xi
[ZZ
] + d
*rm
[ZZ
];
369 /* TOTAL: 47 flops */
373 static int constr_vsiten(t_iatom
*ia
, t_iparams ip
[],
381 n3
= 3*ip
[ia
[0]].vsiten
.n
;
386 for(i
=3; i
<n3
; i
+=3) {
388 a
= ip
[ia
[i
]].vsiten
.a
;
390 pbc_dx_aiuc(pbc
,x
[ai
],x1
,dx
);
392 rvec_sub(x
[ai
],x1
,dx
);
394 dsum
[XX
] += a
*dx
[XX
];
395 dsum
[YY
] += a
*dx
[YY
];
396 dsum
[ZZ
] += a
*dx
[ZZ
];
400 x
[av
][XX
] = x1
[XX
] + dsum
[XX
];
401 x
[av
][YY
] = x1
[YY
] + dsum
[YY
];
402 x
[av
][ZZ
] = x1
[ZZ
] + dsum
[ZZ
];
408 void construct_vsites(FILE *log
,gmx_vsite_t
*vsite
,
409 rvec x
[],t_nrnb
*nrnb
,
411 t_iparams ip
[],t_ilist ilist
[],
412 int ePBC
,bool bMolPBC
,t_graph
*graph
,
413 t_commrec
*cr
,matrix box
)
416 real a1
,b1
,c1
,inv_dt
;
417 int i
,inc
,ii
,nra
,nr
,tp
,ftype
;
418 t_iatom avsite
,ai
,aj
,ak
,al
,pbc_atom
;
420 t_pbc pbc
,*pbc_null
,*pbc_null2
;
422 int *vsite_pbc
,ishift
;
423 rvec reftmp
,vtmp
,rtmp
;
425 bDomDec
= cr
&& DOMAINDECOMP(cr
);
427 /* We only need to do pbc when we have inter-cg vsites */
428 if (ePBC
!= epbcNONE
&& (bDomDec
|| bMolPBC
) && vsite
->n_intercg_vsite
) {
429 /* This is wasting some CPU time as we now do this multiple times
430 * per MD step. But how often do we have vsites with full pbc?
432 pbc_null
= set_pbc_dd(&pbc
,ePBC
,cr
!=NULL
? cr
->dd
: NULL
,FALSE
,box
);
439 dd_move_x_vsites(cr
->dd
,box
,x
);
440 } else if (vsite
->bPDvsitecomm
) {
441 /* I'm not sure whether the periodicity and shift are guaranteed
442 * to be consistent between different nodes when running e.g. polymers
443 * in parallel. In this special case we thus unshift/shift,
444 * but only when necessary. This is to make sure the coordinates
445 * we move don't end up a box away...
448 unshift_self(graph
,box
,x
);
450 move_construct_x(vsite
->vsitecomm
,x
,cr
);
453 shift_self(graph
,box
,x
);
464 for(ftype
=0; (ftype
<F_NRE
); ftype
++) {
465 if (interaction_function
[ftype
].flags
& IF_VSITE
) {
466 nra
= interaction_function
[ftype
].nratoms
;
467 nr
= ilist
[ftype
].nr
;
468 ia
= ilist
[ftype
].iatoms
;
471 vsite_pbc
= vsite
->vsite_pbc_loc
[ftype
-F_VSITE2
];
479 if (ftype != idef->functype[tp])
480 gmx_incons("Function types for vsites wrong");
483 /* The vsite and constructing atoms */
488 /* Constants for constructing vsites */
490 /* Check what kind of pbc we need to use */
492 pbc_atom
= vsite_pbc
[i
/(1+nra
)];
495 /* We need to copy the coordinates here,
496 * single for single atom cg's pbc_atom is the vsite itself.
498 copy_rvec(x
[pbc_atom
],xpbc
);
500 pbc_null2
= pbc_null
;
507 /* Copy the old position */
508 copy_rvec(x
[avsite
],xv
);
510 /* Construct the vsite depending on type */
514 constr_vsite2(x
[ai
],x
[aj
],x
[avsite
],a1
,pbc_null2
);
519 constr_vsite3(x
[ai
],x
[aj
],x
[ak
],x
[avsite
],a1
,b1
,pbc_null2
);
524 constr_vsite3FD(x
[ai
],x
[aj
],x
[ak
],x
[avsite
],a1
,b1
,pbc_null2
);
529 constr_vsite3FAD(x
[ai
],x
[aj
],x
[ak
],x
[avsite
],a1
,b1
,pbc_null2
);
535 constr_vsite3OUT(x
[ai
],x
[aj
],x
[ak
],x
[avsite
],a1
,b1
,c1
,pbc_null2
);
542 constr_vsite4FD(x
[ai
],x
[aj
],x
[ak
],x
[al
],x
[avsite
],a1
,b1
,c1
,
550 constr_vsite4FDN(x
[ai
],x
[aj
],x
[ak
],x
[al
],x
[avsite
],a1
,b1
,c1
,
554 inc
= constr_vsiten(ia
,ip
,x
,pbc_null2
);
557 gmx_fatal(FARGS
,"No such vsite type %d in %s, line %d",
558 ftype
,__FILE__
,__LINE__
);
562 /* Match the pbc of this vsite to the rest of its charge group */
563 ishift
= pbc_dx_aiuc(pbc_null
,x
[avsite
],xpbc
,dx
);
564 if (ishift
!= CENTRAL
)
565 rvec_add(xpbc
,dx
,x
[avsite
]);
568 /* Calculate velocity of vsite... */
569 rvec_sub(x
[avsite
],xv
,vv
);
570 svmul(inv_dt
,vv
,v
[avsite
]);
573 /* Increment loop variables */
581 static void spread_vsite2(t_iatom ia
[],real a
,
582 rvec x
[],rvec f
[],rvec fshift
[],
583 t_pbc
*pbc
,t_graph
*g
)
604 ivec_sub(SHIFT_IVEC(g
,ai
),SHIFT_IVEC(g
,av
),di
);
606 ivec_sub(SHIFT_IVEC(g
,ai
),SHIFT_IVEC(g
,aj
),di
);
609 siv
= pbc_dx_aiuc(pbc
,x
[ai
],x
[av
],dx
);
610 sij
= pbc_dx_aiuc(pbc
,x
[ai
],x
[aj
],dx
);
616 if (fshift
&& (siv
!= CENTRAL
|| sij
!= CENTRAL
)) {
617 rvec_inc(fshift
[siv
],f
[av
]);
618 rvec_dec(fshift
[CENTRAL
],fi
);
619 rvec_dec(fshift
[sij
],fj
);
622 /* TOTAL: 13 flops */
625 void construct_vsites_mtop(FILE *log
,gmx_vsite_t
*vsite
,
626 gmx_mtop_t
*mtop
,rvec x
[])
629 gmx_molblock_t
*molb
;
633 for(mb
=0; mb
<mtop
->nmolblock
; mb
++) {
634 molb
= &mtop
->molblock
[mb
];
635 molt
= &mtop
->moltype
[molb
->type
];
636 for(mol
=0; mol
<molb
->nmol
; mol
++) {
637 construct_vsites(log
,vsite
,x
+as
,NULL
,0.0,NULL
,
638 mtop
->ffparams
.iparams
,molt
->ilist
,
639 epbcNONE
,TRUE
,NULL
,NULL
,NULL
);
640 as
+= molt
->atoms
.nr
;
645 static void spread_vsite3(t_iatom ia
[],real a
,real b
,
646 rvec x
[],rvec f
[],rvec fshift
[],
647 t_pbc
*pbc
,t_graph
*g
)
659 svmul(1-a
-b
,f
[av
],fi
);
670 ivec_sub(SHIFT_IVEC(g
,ai
),SHIFT_IVEC(g
,ia
[1]),di
);
672 ivec_sub(SHIFT_IVEC(g
,ai
),SHIFT_IVEC(g
,aj
),di
);
674 ivec_sub(SHIFT_IVEC(g
,ai
),SHIFT_IVEC(g
,ak
),di
);
677 siv
= pbc_dx_aiuc(pbc
,x
[ai
],x
[av
],dx
);
678 sij
= pbc_dx_aiuc(pbc
,x
[ai
],x
[aj
],dx
);
679 sik
= pbc_dx_aiuc(pbc
,x
[ai
],x
[ak
],dx
);
686 if (fshift
&& (siv
!=CENTRAL
|| sij
!=CENTRAL
|| sik
!=CENTRAL
)) {
687 rvec_inc(fshift
[siv
],f
[av
]);
688 rvec_dec(fshift
[CENTRAL
],fi
);
689 rvec_dec(fshift
[sij
],fj
);
690 rvec_dec(fshift
[sik
],fk
);
693 /* TOTAL: 20 flops */
696 static void spread_vsite3FD(t_iatom ia
[],real a
,real b
,
697 rvec x
[],rvec f
[],rvec fshift
[],
698 t_pbc
*pbc
,t_graph
*g
)
700 real fx
,fy
,fz
,c
,invl
,fproj
,a1
;
701 rvec xvi
,xij
,xjk
,xix
,fv
,temp
;
712 sji
= pbc_rvec_sub(pbc
,x
[aj
],x
[ai
],xij
);
713 skj
= pbc_rvec_sub(pbc
,x
[ak
],x
[aj
],xjk
);
716 /* xix goes from i to point x on the line jk */
717 xix
[XX
]=xij
[XX
]+a
*xjk
[XX
];
718 xix
[YY
]=xij
[YY
]+a
*xjk
[YY
];
719 xix
[ZZ
]=xij
[ZZ
]+a
*xjk
[ZZ
];
722 invl
=gmx_invsqrt(iprod(xix
,xix
));
726 fproj
=iprod(xix
,fv
)*invl
*invl
; /* = (xix . f)/(xix . xix) */
728 temp
[XX
]=c
*(fv
[XX
]-fproj
*xix
[XX
]);
729 temp
[YY
]=c
*(fv
[YY
]-fproj
*xix
[YY
]);
730 temp
[ZZ
]=c
*(fv
[ZZ
]-fproj
*xix
[ZZ
]);
733 /* c is already calculated in constr_vsite3FD
734 storing c somewhere will save 26 flops! */
737 f
[ai
][XX
] += fv
[XX
] - temp
[XX
];
738 f
[ai
][YY
] += fv
[YY
] - temp
[YY
];
739 f
[ai
][ZZ
] += fv
[ZZ
] - temp
[ZZ
];
740 f
[aj
][XX
] += a1
*temp
[XX
];
741 f
[aj
][YY
] += a1
*temp
[YY
];
742 f
[aj
][ZZ
] += a1
*temp
[ZZ
];
743 f
[ak
][XX
] += a
*temp
[XX
];
744 f
[ak
][YY
] += a
*temp
[YY
];
745 f
[ak
][ZZ
] += a
*temp
[ZZ
];
749 ivec_sub(SHIFT_IVEC(g
,ia
[1]),SHIFT_IVEC(g
,ai
),di
);
751 ivec_sub(SHIFT_IVEC(g
,aj
),SHIFT_IVEC(g
,ai
),di
);
753 ivec_sub(SHIFT_IVEC(g
,ak
),SHIFT_IVEC(g
,aj
),di
);
756 svi
= pbc_rvec_sub(pbc
,x
[av
],x
[ai
],xvi
);
761 if (fshift
&& (svi
!=CENTRAL
|| sji
!=CENTRAL
|| skj
!=CENTRAL
)) {
762 rvec_dec(fshift
[svi
],fv
);
763 fshift
[CENTRAL
][XX
] += fv
[XX
] - (1 + a
)*temp
[XX
];
764 fshift
[CENTRAL
][YY
] += fv
[YY
] - (1 + a
)*temp
[YY
];
765 fshift
[CENTRAL
][ZZ
] += fv
[ZZ
] - (1 + a
)*temp
[ZZ
];
766 fshift
[ sji
][XX
] += temp
[XX
];
767 fshift
[ sji
][YY
] += temp
[YY
];
768 fshift
[ sji
][ZZ
] += temp
[ZZ
];
769 fshift
[ skj
][XX
] += a
*temp
[XX
];
770 fshift
[ skj
][YY
] += a
*temp
[YY
];
771 fshift
[ skj
][ZZ
] += a
*temp
[ZZ
];
774 /* TOTAL: 61 flops */
777 static void spread_vsite3FAD(t_iatom ia
[],real a
,real b
,
778 rvec x
[],rvec f
[],rvec fshift
[],
779 t_pbc
*pbc
,t_graph
*g
)
781 rvec xvi
,xij
,xjk
,xperp
,Fpij
,Fppp
,fv
,f1
,f2
,f3
;
782 real a1
,b1
,c1
,c2
,invdij
,invdij2
,invdp
,fproj
;
791 copy_rvec(f
[ia
[1]],fv
);
793 sji
= pbc_rvec_sub(pbc
,x
[aj
],x
[ai
],xij
);
794 skj
= pbc_rvec_sub(pbc
,x
[ak
],x
[aj
],xjk
);
797 invdij
= gmx_invsqrt(iprod(xij
,xij
));
798 invdij2
= invdij
* invdij
;
799 c1
= iprod(xij
,xjk
) * invdij2
;
800 xperp
[XX
] = xjk
[XX
] - c1
*xij
[XX
];
801 xperp
[YY
] = xjk
[YY
] - c1
*xij
[YY
];
802 xperp
[ZZ
] = xjk
[ZZ
] - c1
*xij
[ZZ
];
803 /* xperp in plane ijk, perp. to ij */
804 invdp
= gmx_invsqrt(iprod(xperp
,xperp
));
809 /* a1, b1 and c1 are already calculated in constr_vsite3FAD
810 storing them somewhere will save 45 flops! */
812 fproj
=iprod(xij
,fv
)*invdij2
;
813 svmul(fproj
, xij
, Fpij
); /* proj. f on xij */
814 svmul(iprod(xperp
,fv
)*invdp
*invdp
,xperp
,Fppp
); /* proj. f on xperp */
815 svmul(b1
*fproj
, xperp
,f3
);
818 rvec_sub(fv
,Fpij
,f1
); /* f1 = f - Fpij */
819 rvec_sub(f1
,Fppp
,f2
); /* f2 = f - Fpij - Fppp */
820 for (d
=0; (d
<DIM
); d
++) {
827 f
[ai
][XX
] += fv
[XX
] - f1
[XX
] + c1
*f2
[XX
] + f3
[XX
];
828 f
[ai
][YY
] += fv
[YY
] - f1
[YY
] + c1
*f2
[YY
] + f3
[YY
];
829 f
[ai
][ZZ
] += fv
[ZZ
] - f1
[ZZ
] + c1
*f2
[ZZ
] + f3
[ZZ
];
830 f
[aj
][XX
] += f1
[XX
] - c2
*f2
[XX
] - f3
[XX
];
831 f
[aj
][YY
] += f1
[YY
] - c2
*f2
[YY
] - f3
[YY
];
832 f
[aj
][ZZ
] += f1
[ZZ
] - c2
*f2
[ZZ
] - f3
[ZZ
];
839 ivec_sub(SHIFT_IVEC(g
,ia
[1]),SHIFT_IVEC(g
,ai
),di
);
841 ivec_sub(SHIFT_IVEC(g
,aj
),SHIFT_IVEC(g
,ai
),di
);
843 ivec_sub(SHIFT_IVEC(g
,ak
),SHIFT_IVEC(g
,aj
),di
);
846 svi
= pbc_rvec_sub(pbc
,x
[av
],x
[ai
],xvi
);
851 if (fshift
&& (svi
!=CENTRAL
|| sji
!=CENTRAL
|| skj
!=CENTRAL
)) {
852 rvec_dec(fshift
[svi
],fv
);
853 fshift
[CENTRAL
][XX
] += fv
[XX
] - f1
[XX
] - (1-c1
)*f2
[XX
] + f3
[XX
];
854 fshift
[CENTRAL
][YY
] += fv
[YY
] - f1
[YY
] - (1-c1
)*f2
[YY
] + f3
[YY
];
855 fshift
[CENTRAL
][ZZ
] += fv
[ZZ
] - f1
[ZZ
] - (1-c1
)*f2
[ZZ
] + f3
[ZZ
];
856 fshift
[ sji
][XX
] += f1
[XX
] - c1
*f2
[XX
] - f3
[XX
];
857 fshift
[ sji
][YY
] += f1
[YY
] - c1
*f2
[YY
] - f3
[YY
];
858 fshift
[ sji
][ZZ
] += f1
[ZZ
] - c1
*f2
[ZZ
] - f3
[ZZ
];
859 fshift
[ skj
][XX
] += f2
[XX
];
860 fshift
[ skj
][YY
] += f2
[YY
];
861 fshift
[ skj
][ZZ
] += f2
[ZZ
];
864 /* TOTAL: 113 flops */
867 static void spread_vsite3OUT(t_iatom ia
[],real a
,real b
,real c
,
868 rvec x
[],rvec f
[],rvec fshift
[],
869 t_pbc
*pbc
,t_graph
*g
)
871 rvec xvi
,xij
,xik
,fv
,fj
,fk
;
882 sji
= pbc_rvec_sub(pbc
,x
[aj
],x
[ai
],xij
);
883 ski
= pbc_rvec_sub(pbc
,x
[ak
],x
[ai
],xik
);
893 fj
[XX
] = a
*fv
[XX
] - xik
[ZZ
]*cfy
+ xik
[YY
]*cfz
;
894 fj
[YY
] = xik
[ZZ
]*cfx
+ a
*fv
[YY
] - xik
[XX
]*cfz
;
895 fj
[ZZ
] = -xik
[YY
]*cfx
+ xik
[XX
]*cfy
+ a
*fv
[ZZ
];
897 fk
[XX
] = b
*fv
[XX
] + xij
[ZZ
]*cfy
- xij
[YY
]*cfz
;
898 fk
[YY
] = -xij
[ZZ
]*cfx
+ b
*fv
[YY
] + xij
[XX
]*cfz
;
899 fk
[ZZ
] = xij
[YY
]*cfx
- xij
[XX
]*cfy
+ b
*fv
[ZZ
];
902 f
[ai
][XX
] += fv
[XX
] - fj
[XX
] - fk
[XX
];
903 f
[ai
][YY
] += fv
[YY
] - fj
[YY
] - fk
[YY
];
904 f
[ai
][ZZ
] += fv
[ZZ
] - fj
[ZZ
] - fk
[ZZ
];
910 ivec_sub(SHIFT_IVEC(g
,ia
[1]),SHIFT_IVEC(g
,ai
),di
);
912 ivec_sub(SHIFT_IVEC(g
,aj
),SHIFT_IVEC(g
,ai
),di
);
914 ivec_sub(SHIFT_IVEC(g
,ak
),SHIFT_IVEC(g
,ai
),di
);
917 svi
= pbc_rvec_sub(pbc
,x
[av
],x
[ai
],xvi
);
922 if (fshift
&& (svi
!=CENTRAL
|| sji
!=CENTRAL
|| ski
!=CENTRAL
)) {
923 rvec_dec(fshift
[svi
],fv
);
924 fshift
[CENTRAL
][XX
] += fv
[XX
] - fj
[XX
] - fk
[XX
];
925 fshift
[CENTRAL
][YY
] += fv
[YY
] - fj
[YY
] - fk
[YY
];
926 fshift
[CENTRAL
][ZZ
] += fv
[ZZ
] - fj
[ZZ
] - fk
[ZZ
];
927 rvec_inc(fshift
[sji
],fj
);
928 rvec_inc(fshift
[ski
],fk
);
931 /* TOTAL: 54 flops */
934 static void spread_vsite4FD(t_iatom ia
[],real a
,real b
,real c
,
935 rvec x
[],rvec f
[],rvec fshift
[],
936 t_pbc
*pbc
,t_graph
*g
)
938 real d
,invl
,fproj
,a1
;
939 rvec xvi
,xij
,xjk
,xjl
,xix
,fv
,temp
;
940 atom_id av
,ai
,aj
,ak
,al
;
942 int svi
,sji
,skj
,slj
,m
;
950 sji
= pbc_rvec_sub(pbc
,x
[aj
],x
[ai
],xij
);
951 skj
= pbc_rvec_sub(pbc
,x
[ak
],x
[aj
],xjk
);
952 slj
= pbc_rvec_sub(pbc
,x
[al
],x
[aj
],xjl
);
955 /* xix goes from i to point x on the plane jkl */
957 xix
[m
] = xij
[m
] + a
*xjk
[m
] + b
*xjl
[m
];
960 invl
=gmx_invsqrt(iprod(xix
,xix
));
966 fproj
=iprod(xix
,fv
)*invl
*invl
; /* = (xix . f)/(xix . xix) */
969 temp
[m
] = d
*(fv
[m
] - fproj
*xix
[m
]);
972 /* c is already calculated in constr_vsite3FD
973 storing c somewhere will save 35 flops! */
976 for(m
=0; m
<DIM
; m
++) {
977 f
[ai
][m
] += fv
[m
] - temp
[m
];
978 f
[aj
][m
] += a1
*temp
[m
];
979 f
[ak
][m
] += a
*temp
[m
];
980 f
[al
][m
] += b
*temp
[m
];
985 ivec_sub(SHIFT_IVEC(g
,ia
[1]),SHIFT_IVEC(g
,ai
),di
);
987 ivec_sub(SHIFT_IVEC(g
,aj
),SHIFT_IVEC(g
,ai
),di
);
989 ivec_sub(SHIFT_IVEC(g
,ak
),SHIFT_IVEC(g
,aj
),di
);
991 ivec_sub(SHIFT_IVEC(g
,al
),SHIFT_IVEC(g
,aj
),di
);
994 svi
= pbc_rvec_sub(pbc
,x
[av
],x
[ai
],xvi
);
1000 (svi
!=CENTRAL
|| sji
!=CENTRAL
|| skj
!=CENTRAL
|| slj
!=CENTRAL
)) {
1001 rvec_dec(fshift
[svi
],fv
);
1002 for(m
=0; m
<DIM
; m
++) {
1003 fshift
[CENTRAL
][m
] += fv
[m
] - (1 + a
+ b
)*temp
[m
];
1004 fshift
[ sji
][m
] += temp
[m
];
1005 fshift
[ skj
][m
] += a
*temp
[m
];
1006 fshift
[ slj
][m
] += b
*temp
[m
];
1010 /* TOTAL: 77 flops */
1014 static void spread_vsite4FDN(t_iatom ia
[],real a
,real b
,real c
,
1015 rvec x
[],rvec f
[],rvec fshift
[],
1016 t_pbc
*pbc
,t_graph
*g
)
1018 rvec xvi
,xij
,xik
,xil
,ra
,rb
,rja
,rjb
,rab
,rm
,rt
;
1024 int svi
,sij
,sik
,sil
;
1026 /* DEBUG: check atom indices */
1033 copy_rvec(f
[av
],fv
);
1035 sij
= pbc_rvec_sub(pbc
,x
[aj
],x
[ai
],xij
);
1036 sik
= pbc_rvec_sub(pbc
,x
[ak
],x
[ai
],xik
);
1037 sil
= pbc_rvec_sub(pbc
,x
[al
],x
[ai
],xil
);
1050 rvec_sub(ra
,xij
,rja
);
1051 rvec_sub(rb
,xij
,rjb
);
1052 rvec_sub(rb
,ra
,rab
);
1058 invrm
=gmx_invsqrt(norm2(rm
));
1062 cfx
= c
*invrm
*fv
[XX
];
1063 cfy
= c
*invrm
*fv
[YY
];
1064 cfz
= c
*invrm
*fv
[ZZ
];
1075 fj
[XX
] = ( -rm
[XX
]*rt
[XX
]) * cfx
+ ( rab
[ZZ
]-rm
[YY
]*rt
[XX
]) * cfy
+ (-rab
[YY
]-rm
[ZZ
]*rt
[XX
]) * cfz
;
1076 fj
[YY
] = (-rab
[ZZ
]-rm
[XX
]*rt
[YY
]) * cfx
+ ( -rm
[YY
]*rt
[YY
]) * cfy
+ ( rab
[XX
]-rm
[ZZ
]*rt
[YY
]) * cfz
;
1077 fj
[ZZ
] = ( rab
[YY
]-rm
[XX
]*rt
[ZZ
]) * cfx
+ (-rab
[XX
]-rm
[YY
]*rt
[ZZ
]) * cfy
+ ( -rm
[ZZ
]*rt
[ZZ
]) * cfz
;
1088 fk
[XX
] = ( -rm
[XX
]*rt
[XX
]) * cfx
+ (-a
*rjb
[ZZ
]-rm
[YY
]*rt
[XX
]) * cfy
+ ( a
*rjb
[YY
]-rm
[ZZ
]*rt
[XX
]) * cfz
;
1089 fk
[YY
] = ( a
*rjb
[ZZ
]-rm
[XX
]*rt
[YY
]) * cfx
+ ( -rm
[YY
]*rt
[YY
]) * cfy
+ (-a
*rjb
[XX
]-rm
[ZZ
]*rt
[YY
]) * cfz
;
1090 fk
[ZZ
] = (-a
*rjb
[YY
]-rm
[XX
]*rt
[ZZ
]) * cfx
+ ( a
*rjb
[XX
]-rm
[YY
]*rt
[ZZ
]) * cfy
+ ( -rm
[ZZ
]*rt
[ZZ
]) * cfz
;
1101 fl
[XX
] = ( -rm
[XX
]*rt
[XX
]) * cfx
+ ( b
*rja
[ZZ
]-rm
[YY
]*rt
[XX
]) * cfy
+ (-b
*rja
[YY
]-rm
[ZZ
]*rt
[XX
]) * cfz
;
1102 fl
[YY
] = (-b
*rja
[ZZ
]-rm
[XX
]*rt
[YY
]) * cfx
+ ( -rm
[YY
]*rt
[YY
]) * cfy
+ ( b
*rja
[XX
]-rm
[ZZ
]*rt
[YY
]) * cfz
;
1103 fl
[ZZ
] = ( b
*rja
[YY
]-rm
[XX
]*rt
[ZZ
]) * cfx
+ (-b
*rja
[XX
]-rm
[YY
]*rt
[ZZ
]) * cfy
+ ( -rm
[ZZ
]*rt
[ZZ
]) * cfz
;
1106 f
[ai
][XX
] += fv
[XX
] - fj
[XX
] - fk
[XX
] - fl
[XX
];
1107 f
[ai
][YY
] += fv
[YY
] - fj
[YY
] - fk
[YY
] - fl
[YY
];
1108 f
[ai
][ZZ
] += fv
[ZZ
] - fj
[ZZ
] - fk
[ZZ
] - fl
[ZZ
];
1115 ivec_sub(SHIFT_IVEC(g
,av
),SHIFT_IVEC(g
,ai
),di
);
1117 ivec_sub(SHIFT_IVEC(g
,aj
),SHIFT_IVEC(g
,ai
),di
);
1119 ivec_sub(SHIFT_IVEC(g
,ak
),SHIFT_IVEC(g
,ai
),di
);
1121 ivec_sub(SHIFT_IVEC(g
,al
),SHIFT_IVEC(g
,ai
),di
);
1124 svi
= pbc_rvec_sub(pbc
,x
[av
],x
[ai
],xvi
);
1129 if (fshift
&& (svi
!=CENTRAL
|| sij
!=CENTRAL
|| sik
!=CENTRAL
|| sil
!=CENTRAL
)) {
1130 rvec_dec(fshift
[svi
],fv
);
1131 fshift
[CENTRAL
][XX
] += fv
[XX
] - fj
[XX
] - fk
[XX
] - fl
[XX
];
1132 fshift
[CENTRAL
][YY
] += fv
[YY
] - fj
[YY
] - fk
[YY
] - fl
[YY
];
1133 fshift
[CENTRAL
][ZZ
] += fv
[ZZ
] - fj
[ZZ
] - fk
[ZZ
] - fl
[ZZ
];
1134 rvec_inc(fshift
[sij
],fj
);
1135 rvec_inc(fshift
[sik
],fk
);
1136 rvec_inc(fshift
[sil
],fl
);
1139 /* Total: 207 flops (Yuck!) */
1143 static int spread_vsiten(t_iatom ia
[],t_iparams ip
[],
1144 rvec x
[],rvec f
[],rvec fshift
[],
1145 t_pbc
*pbc
,t_graph
*g
)
1153 n3
= 3*ip
[ia
[0]].vsiten
.n
;
1155 copy_rvec(x
[av
],xv
);
1157 for(i
=0; i
<n3
; i
+=3) {
1160 ivec_sub(SHIFT_IVEC(g
,ai
),SHIFT_IVEC(g
,av
),di
);
1163 siv
= pbc_dx_aiuc(pbc
,x
[ai
],xv
,dx
);
1167 a
= ip
[ia
[i
]].vsiten
.a
;
1170 if (fshift
&& siv
!= CENTRAL
) {
1171 rvec_inc(fshift
[siv
],fi
);
1172 rvec_dec(fshift
[CENTRAL
],fi
);
1181 void spread_vsite_f(FILE *log
,gmx_vsite_t
*vsite
,
1182 rvec x
[],rvec f
[],rvec
*fshift
,
1183 t_nrnb
*nrnb
,t_idef
*idef
,
1184 int ePBC
,bool bMolPBC
,t_graph
*g
,matrix box
,
1188 int i
,inc
,m
,nra
,nr
,tp
,ftype
;
1189 int nd2
,nd3
,nd3FD
,nd3FAD
,nd3OUT
,nd4FD
,nd4FDN
,ndN
;
1192 t_pbc pbc
,*pbc_null
,*pbc_null2
;
1195 /* We only need to do pbc when we have inter-cg vsites */
1196 if ((DOMAINDECOMP(cr
) || bMolPBC
) && vsite
->n_intercg_vsite
) {
1197 /* This is wasting some CPU time as we now do this multiple times
1198 * per MD step. But how often do we have vsites with full pbc?
1200 pbc_null
= set_pbc_dd(&pbc
,ePBC
,cr
->dd
,FALSE
,box
);
1205 if (DOMAINDECOMP(cr
))
1207 dd_clear_f_vsites(cr
->dd
,f
);
1209 else if (PARTDECOMP(cr
) && vsite
->vsitecomm
!= NULL
)
1211 pd_clear_nonlocal_constructs(vsite
->vsitecomm
,f
);
1225 /* this loop goes backwards to be able to build *
1226 * higher type vsites from lower types */
1228 for(ftype
=F_NRE
-1; (ftype
>=0); ftype
--) {
1229 if (interaction_function
[ftype
].flags
& IF_VSITE
) {
1230 nra
= interaction_function
[ftype
].nratoms
;
1231 nr
= idef
->il
[ftype
].nr
;
1232 ia
= idef
->il
[ftype
].iatoms
;
1235 vsite_pbc
= vsite
->vsite_pbc_loc
[ftype
-F_VSITE2
];
1240 for(i
=0; (i
<nr
); ) {
1241 /* Check if we need to apply pbc for this vsite */
1243 if (vsite_pbc
[i
/(1+nra
)] > -2)
1244 pbc_null2
= pbc_null
;
1250 if (ftype
!= idef
->functype
[tp
])
1251 gmx_incons("Functiontypes for vsites wrong");
1253 /* Constants for constructing */
1254 a1
= ip
[tp
].vsite
.a
;
1255 /* Construct the vsite depending on type */
1259 spread_vsite2(ia
,a1
,x
,f
,fshift
,pbc_null2
,g
);
1263 b1
= ip
[tp
].vsite
.b
;
1264 spread_vsite3(ia
,a1
,b1
,x
,f
,fshift
,pbc_null2
,g
);
1268 b1
= ip
[tp
].vsite
.b
;
1269 spread_vsite3FD(ia
,a1
,b1
,x
,f
,fshift
,pbc_null2
,g
);
1273 b1
= ip
[tp
].vsite
.b
;
1274 spread_vsite3FAD(ia
,a1
,b1
,x
,f
,fshift
,pbc_null2
,g
);
1278 b1
= ip
[tp
].vsite
.b
;
1279 c1
= ip
[tp
].vsite
.c
;
1280 spread_vsite3OUT(ia
,a1
,b1
,c1
,x
,f
,fshift
,pbc_null2
,g
);
1284 b1
= ip
[tp
].vsite
.b
;
1285 c1
= ip
[tp
].vsite
.c
;
1286 spread_vsite4FD(ia
,a1
,b1
,c1
,x
,f
,fshift
,pbc_null2
,g
);
1290 b1
= ip
[tp
].vsite
.b
;
1291 c1
= ip
[tp
].vsite
.c
;
1292 spread_vsite4FDN(ia
,a1
,b1
,c1
,x
,f
,fshift
,pbc_null2
,g
);
1296 inc
= spread_vsiten(ia
,ip
,x
,f
,fshift
,pbc_null2
,g
);
1300 gmx_fatal(FARGS
,"No such vsite type %d in %s, line %d",
1301 ftype
,__FILE__
,__LINE__
);
1303 clear_rvec(f
[ia
[1]]);
1305 /* Increment loop variables */
1312 inc_nrnb(nrnb
,eNR_VSITE2
, nd2
);
1313 inc_nrnb(nrnb
,eNR_VSITE3
, nd3
);
1314 inc_nrnb(nrnb
,eNR_VSITE3FD
, nd3FD
);
1315 inc_nrnb(nrnb
,eNR_VSITE3FAD
,nd3FAD
);
1316 inc_nrnb(nrnb
,eNR_VSITE3OUT
,nd3OUT
);
1317 inc_nrnb(nrnb
,eNR_VSITE4FD
, nd4FD
);
1318 inc_nrnb(nrnb
,eNR_VSITE4FDN
,nd4FDN
);
1319 inc_nrnb(nrnb
,eNR_VSITEN
, ndN
);
1321 if (DOMAINDECOMP(cr
)) {
1322 dd_move_f_vsites(cr
->dd
,f
,fshift
);
1323 } else if (vsite
->bPDvsitecomm
) {
1324 /* We only move forces here, and they are independent of shifts */
1325 move_construct_f(vsite
->vsitecomm
,f
,cr
);
1329 static int *atom2cg(t_block
*cgs
)
1333 snew(a2cg
,cgs
->index
[cgs
->nr
]);
1334 for(cg
=0; cg
<cgs
->nr
; cg
++) {
1335 for(i
=cgs
->index
[cg
]; i
<cgs
->index
[cg
+1]; i
++)
1342 static int count_intercg_vsite(gmx_mtop_t
*mtop
)
1344 int mb
,mt
,ftype
,nral
,i
,cg
,a
;
1345 gmx_molblock_t
*molb
;
1346 gmx_moltype_t
*molt
;
1350 int n_intercg_vsite
;
1352 n_intercg_vsite
= 0;
1353 for(mb
=0; mb
<mtop
->nmolblock
; mb
++) {
1354 molb
= &mtop
->molblock
[mb
];
1355 molt
= &mtop
->moltype
[molb
->type
];
1356 a2cg
= atom2cg(&molt
->cgs
);
1357 for(ftype
=0; ftype
<F_NRE
; ftype
++) {
1358 if (interaction_function
[ftype
].flags
& IF_VSITE
) {
1360 il
= &molt
->ilist
[ftype
];
1362 for(i
=0; i
<il
->nr
; i
+=1+nral
) {
1364 for(a
=1; a
<nral
; a
++) {
1365 if (a2cg
[ia
[1+a
]] != cg
) {
1366 n_intercg_vsite
+= molb
->nmol
;
1376 return n_intercg_vsite
;
1379 static int **get_vsite_pbc(t_iparams
*iparams
,t_ilist
*ilist
,
1380 t_atom
*atom
,t_mdatoms
*md
,
1381 t_block
*cgs
,int *a2cg
)
1383 int ftype
,nral
,i
,j
,vsi
,vsite
,cg_v
,cg_c
,a
,nc3
=0;
1386 int **vsite_pbc
,*vsite_pbc_f
;
1388 bool bViteOnlyCG_and_FirstAtom
;
1390 /* Make an array that tells if the pbc of an atom is set */
1391 snew(pbc_set
,cgs
->index
[cgs
->nr
]);
1392 /* PBC is set for all non vsites */
1393 for(a
=0; a
<cgs
->index
[cgs
->nr
]; a
++) {
1394 if ((atom
&& atom
[a
].ptype
!= eptVSite
) ||
1395 (md
&& md
->ptype
[a
] != eptVSite
)) {
1400 snew(vsite_pbc
,F_VSITEN
-F_VSITE2
+1);
1402 for(ftype
=0; ftype
<F_NRE
; ftype
++) {
1403 if (interaction_function
[ftype
].flags
& IF_VSITE
) {
1408 snew(vsite_pbc
[ftype
-F_VSITE2
],il
->nr
/(1+nral
));
1409 vsite_pbc_f
= vsite_pbc
[ftype
-F_VSITE2
];
1412 while (i
< il
->nr
) {
1416 /* A value of -2 signals that this vsite and its contructing
1417 * atoms are all within the same cg, so no pbc is required.
1419 vsite_pbc_f
[vsi
] = -2;
1420 /* Check if constructing atoms are outside the vsite's cg */
1422 if (ftype
== F_VSITEN
) {
1423 nc3
= 3*iparams
[ia
[i
]].vsiten
.n
;
1424 for(j
=0; j
<nc3
; j
+=3) {
1425 if (a2cg
[ia
[i
+j
+2]] != cg_v
)
1426 vsite_pbc_f
[vsi
] = -1;
1429 for(a
=1; a
<nral
; a
++) {
1430 if (a2cg
[ia
[i
+1+a
]] != cg_v
)
1431 vsite_pbc_f
[vsi
] = -1;
1434 if (vsite_pbc_f
[vsi
] == -1) {
1435 /* Check if this is the first processed atom of a vsite only cg */
1436 bViteOnlyCG_and_FirstAtom
= TRUE
;
1437 for(a
=cgs
->index
[cg_v
]; a
<cgs
->index
[cg_v
+1]; a
++) {
1438 /* Non-vsites already have pbc set, so simply check for pbc_set */
1440 bViteOnlyCG_and_FirstAtom
= FALSE
;
1444 if (bViteOnlyCG_and_FirstAtom
) {
1445 /* First processed atom of a vsite only charge group.
1446 * The pbc of the input coordinates to construct_vsites
1447 * should be preserved.
1449 vsite_pbc_f
[vsi
] = vsite
;
1450 } else if (cg_v
!= a2cg
[ia
[1+i
+1]]) {
1451 /* This vsite has a different charge group index
1452 * than it's first constructing atom
1453 * and the charge group has more than one atom,
1454 * search for the first normal particle
1455 * or vsite that already had its pbc defined.
1456 * If nothing is found, use full pbc for this vsite.
1458 for(a
=cgs
->index
[cg_v
]; a
<cgs
->index
[cg_v
+1]; a
++) {
1459 if (a
!= vsite
&& pbc_set
[a
]) {
1460 vsite_pbc_f
[vsi
] = a
;
1462 fprintf(debug
,"vsite %d match pbc with atom %d\n",
1468 fprintf(debug
,"vsite atom %d cg %d - %d pbc atom %d\n",
1469 vsite
+1,cgs
->index
[cg_v
]+1,cgs
->index
[cg_v
+1],
1470 vsite_pbc_f
[vsi
]+1);
1473 if (ftype
== F_VSITEN
) {
1474 /* The other entries in vsite_pbc_f are not used for center vsites */
1480 /* This vsite now has its pbc defined */
1491 gmx_vsite_t
*init_vsite(gmx_mtop_t
*mtop
,t_commrec
*cr
)
1497 gmx_moltype_t
*molt
;
1499 /* check if there are vsites */
1501 for(i
=0; i
<F_NRE
; i
++) {
1502 if (interaction_function
[i
].flags
& IF_VSITE
) {
1503 nvsite
+= gmx_mtop_ftype_count(mtop
,i
);
1513 vsite
->n_intercg_vsite
= count_intercg_vsite(mtop
);
1515 if (vsite
->n_intercg_vsite
> 0 && DOMAINDECOMP(cr
)) {
1516 vsite
->nvsite_pbc_molt
= mtop
->nmoltype
;
1517 snew(vsite
->vsite_pbc_molt
,vsite
->nvsite_pbc_molt
);
1518 for(mt
=0; mt
<mtop
->nmoltype
; mt
++) {
1519 molt
= &mtop
->moltype
[mt
];
1520 /* Make an atom to charge group index */
1521 a2cg
= atom2cg(&molt
->cgs
);
1522 vsite
->vsite_pbc_molt
[mt
] = get_vsite_pbc(mtop
->ffparams
.iparams
,
1524 molt
->atoms
.atom
,NULL
,
1529 snew(vsite
->vsite_pbc_loc_nalloc
,F_VSITEN
-F_VSITE2
+1);
1530 snew(vsite
->vsite_pbc_loc
,F_VSITEN
-F_VSITE2
+1);
1537 void set_vsite_top(gmx_vsite_t
*vsite
,gmx_localtop_t
*top
,t_mdatoms
*md
,
1542 /* Make an atom to charge group index */
1543 a2cg
= atom2cg(&top
->cgs
);
1545 if (vsite
->n_intercg_vsite
> 0) {
1546 vsite
->vsite_pbc_loc
= get_vsite_pbc(top
->idef
.iparams
,
1547 top
->idef
.il
,NULL
,md
,
1550 if (PARTDECOMP(cr
)) {
1551 snew(vsite
->vsitecomm
,1);
1552 vsite
->bPDvsitecomm
=
1553 setup_parallel_vsites(&(top
->idef
),cr
,vsite
->vsitecomm
);