4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
27 * Green Red Orange Magenta Azure Cyan Skyblue
33 static char *SRCID_vec_h
= "$Id$";
36 #ident "@(#) vec.h 1.8 12/16/92"
37 #endif /* HAVE_IDENT */
47 #define gmx_inline inline
53 static gmx_inline real
invsqrt(float x
)
57 t_convert result
,bit_pattern
;
66 exp
= EXP_ADDR(bit_pattern
.bval
);
67 fract
= FRACT_ADDR(bit_pattern
.bval
);
68 result
.bval
=lookup_table
.exp_seed
[exp
] | lookup_table
.fract_seed
[fract
];
71 y
=(half
*lu
*(three
-((x
*lu
)*lu
)));
73 y2
=(half
*y
*(three
-((x
*y
)*y
)));
75 return y2
; /* 10 Flops */
77 return y
; /* 5 Flops */
84 #define invsqrt(x) (1.0f/sqrt(x))
87 static gmx_inline real
sqr(real x
)
92 static gmx_inline
void rvec_add(rvec a
,rvec b
,rvec c
)
105 static gmx_inline
void rvec_inc(rvec a
,rvec b
)
118 static gmx_inline
void rvec_sub(rvec a
,rvec b
,rvec c
)
131 static gmx_inline
void rvec_dec(rvec a
,rvec b
)
144 static gmx_inline
void copy_rvec(rvec a
,rvec b
)
151 static gmx_inline
void copy_mat(matrix a
,matrix b
)
153 copy_rvec(a
[XX
],b
[XX
]);
154 copy_rvec(a
[YY
],b
[YY
]);
155 copy_rvec(a
[ZZ
],b
[ZZ
]);
158 static gmx_inline
void svmul(real a
,rvec v1
,rvec v2
)
165 static gmx_inline real
distance2(rvec v1
, rvec v2
)
167 return sqr(v2
[XX
]-v1
[XX
]) + sqr(v2
[YY
]-v1
[YY
]) + sqr(v2
[ZZ
]-v1
[ZZ
]);
170 static gmx_inline
void clear_rvec(rvec a
)
174 a
[XX
]=a
[YY
]=a
[ZZ
]=nul
;
177 static gmx_inline
void clear_rvecs(int n
,rvec v
[])
185 static gmx_inline
void clear_mat(matrix a
)
189 a
[XX
][XX
]=a
[XX
][YY
]=a
[XX
][ZZ
]=nul
;
190 a
[YY
][XX
]=a
[YY
][YY
]=a
[YY
][ZZ
]=nul
;
191 a
[ZZ
][XX
]=a
[ZZ
][YY
]=a
[ZZ
][ZZ
]=nul
;
194 static gmx_inline real
iprod(rvec a
,rvec b
)
196 return (a
[XX
]*b
[XX
]+a
[YY
]*b
[YY
]+a
[ZZ
]*b
[ZZ
]);
199 static gmx_inline real
norm2(rvec a
)
201 return a
[XX
]*a
[XX
]+a
[YY
]*a
[YY
]+a
[ZZ
]*a
[ZZ
];
204 static gmx_inline real
norm(rvec a
)
206 return sqrt(a
[XX
]*a
[XX
]+a
[YY
]*a
[YY
]+a
[ZZ
]*a
[ZZ
]);
209 static gmx_inline real
cos_angle(rvec a
,rvec b
)
212 * ax*bx + ay*by + az*bz
213 * cos-vec (a,b) = ---------------------
218 double aa
,bb
,ip
,ipa
,ipb
; /* For accuracy these must be double! */
221 for(m
=0; (m
<DIM
); m
++) { /* 18 */
228 cos
=ip
*invsqrt(ipa
*ipb
); /* 7 */
238 static gmx_inline
void oprod(rvec a
,rvec b
,rvec c
)
240 c
[XX
]=a
[YY
]*b
[ZZ
]-a
[ZZ
]*b
[YY
];
241 c
[YY
]=a
[ZZ
]*b
[XX
]-a
[XX
]*b
[ZZ
];
242 c
[ZZ
]=a
[XX
]*b
[YY
]-a
[YY
]*b
[XX
];
245 static gmx_inline
void mmul(matrix a
,matrix b
,matrix dest
)
247 dest
[XX
][XX
]=a
[XX
][XX
]*b
[XX
][XX
]+a
[XX
][YY
]*b
[YY
][XX
]+a
[XX
][ZZ
]*b
[ZZ
][XX
];
248 dest
[YY
][XX
]=a
[YY
][XX
]*b
[XX
][XX
]+a
[YY
][YY
]*b
[YY
][XX
]+a
[YY
][ZZ
]*b
[ZZ
][XX
];
249 dest
[ZZ
][XX
]=a
[ZZ
][XX
]*b
[XX
][XX
]+a
[ZZ
][YY
]*b
[YY
][XX
]+a
[ZZ
][ZZ
]*b
[ZZ
][XX
];
250 dest
[XX
][YY
]=a
[XX
][XX
]*b
[XX
][YY
]+a
[XX
][YY
]*b
[YY
][YY
]+a
[XX
][ZZ
]*b
[ZZ
][YY
];
251 dest
[YY
][YY
]=a
[YY
][XX
]*b
[XX
][YY
]+a
[YY
][YY
]*b
[YY
][YY
]+a
[YY
][ZZ
]*b
[ZZ
][YY
];
252 dest
[ZZ
][YY
]=a
[ZZ
][XX
]*b
[XX
][YY
]+a
[ZZ
][YY
]*b
[YY
][YY
]+a
[ZZ
][ZZ
]*b
[ZZ
][YY
];
253 dest
[XX
][ZZ
]=a
[XX
][XX
]*b
[XX
][ZZ
]+a
[XX
][YY
]*b
[YY
][ZZ
]+a
[XX
][ZZ
]*b
[ZZ
][ZZ
];
254 dest
[YY
][ZZ
]=a
[YY
][XX
]*b
[XX
][ZZ
]+a
[YY
][YY
]*b
[YY
][ZZ
]+a
[YY
][ZZ
]*b
[ZZ
][ZZ
];
255 dest
[ZZ
][ZZ
]=a
[ZZ
][XX
]*b
[XX
][ZZ
]+a
[ZZ
][YY
]*b
[YY
][ZZ
]+a
[ZZ
][ZZ
]*b
[ZZ
][ZZ
];
258 static gmx_inline real
det(matrix a
)
260 return ( a
[XX
][XX
]*(a
[YY
][YY
]*a
[ZZ
][ZZ
]-a
[ZZ
][YY
]*a
[YY
][ZZ
])
261 -a
[YY
][XX
]*(a
[XX
][YY
]*a
[ZZ
][ZZ
]-a
[ZZ
][YY
]*a
[XX
][ZZ
])
262 +a
[ZZ
][XX
]*(a
[XX
][YY
]*a
[YY
][ZZ
]-a
[YY
][YY
]*a
[XX
][ZZ
]));
265 static gmx_inline
void m_add(matrix a
,matrix b
,matrix dest
)
267 dest
[XX
][XX
]=a
[XX
][XX
]+b
[XX
][XX
];
268 dest
[XX
][YY
]=a
[XX
][YY
]+b
[XX
][YY
];
269 dest
[XX
][ZZ
]=a
[XX
][ZZ
]+b
[XX
][ZZ
];
270 dest
[YY
][XX
]=a
[YY
][XX
]+b
[YY
][XX
];
271 dest
[YY
][YY
]=a
[YY
][YY
]+b
[YY
][YY
];
272 dest
[YY
][ZZ
]=a
[YY
][ZZ
]+b
[YY
][ZZ
];
273 dest
[ZZ
][XX
]=a
[ZZ
][XX
]+b
[ZZ
][XX
];
274 dest
[ZZ
][YY
]=a
[ZZ
][YY
]+b
[ZZ
][YY
];
275 dest
[ZZ
][ZZ
]=a
[ZZ
][ZZ
]+b
[ZZ
][ZZ
];
278 static gmx_inline
void m_sub(matrix a
,matrix b
,matrix dest
)
280 dest
[XX
][XX
]=a
[XX
][XX
]-b
[XX
][XX
];
281 dest
[XX
][YY
]=a
[XX
][YY
]-b
[XX
][YY
];
282 dest
[XX
][ZZ
]=a
[XX
][ZZ
]-b
[XX
][ZZ
];
283 dest
[YY
][XX
]=a
[YY
][XX
]-b
[YY
][XX
];
284 dest
[YY
][YY
]=a
[YY
][YY
]-b
[YY
][YY
];
285 dest
[YY
][ZZ
]=a
[YY
][ZZ
]-b
[YY
][ZZ
];
286 dest
[ZZ
][XX
]=a
[ZZ
][XX
]-b
[ZZ
][XX
];
287 dest
[ZZ
][YY
]=a
[ZZ
][YY
]-b
[ZZ
][YY
];
288 dest
[ZZ
][ZZ
]=a
[ZZ
][ZZ
]-b
[ZZ
][ZZ
];
291 static gmx_inline
void msmul(matrix m1
,real r1
,matrix dest
)
293 dest
[XX
][XX
]=r1
*m1
[XX
][XX
];
294 dest
[XX
][YY
]=r1
*m1
[XX
][YY
];
295 dest
[XX
][ZZ
]=r1
*m1
[XX
][ZZ
];
296 dest
[YY
][XX
]=r1
*m1
[YY
][XX
];
297 dest
[YY
][YY
]=r1
*m1
[YY
][YY
];
298 dest
[YY
][ZZ
]=r1
*m1
[YY
][ZZ
];
299 dest
[ZZ
][XX
]=r1
*m1
[ZZ
][XX
];
300 dest
[ZZ
][YY
]=r1
*m1
[ZZ
][YY
];
301 dest
[ZZ
][ZZ
]=r1
*m1
[ZZ
][ZZ
];
304 static gmx_inline
void m_inv(matrix src
,matrix dest
)
306 const real smallreal
= 1.0e-18;
307 const real largereal
= 1.0e18
;
314 if ((fc
<= smallreal
) || (fc
>= largereal
))
315 fatal_error(0,"Determinant = %f",1.0/c
);
317 dest
[XX
][XX
]= c
*(src
[YY
][YY
]*src
[ZZ
][ZZ
]-src
[ZZ
][YY
]*src
[YY
][ZZ
]);
318 dest
[XX
][YY
]=-c
*(src
[XX
][YY
]*src
[ZZ
][ZZ
]-src
[ZZ
][YY
]*src
[XX
][ZZ
]);
319 dest
[XX
][ZZ
]= c
*(src
[XX
][YY
]*src
[YY
][ZZ
]-src
[YY
][YY
]*src
[XX
][ZZ
]);
320 dest
[YY
][XX
]=-c
*(src
[YY
][XX
]*src
[ZZ
][ZZ
]-src
[ZZ
][XX
]*src
[YY
][ZZ
]);
321 dest
[YY
][YY
]= c
*(src
[XX
][XX
]*src
[ZZ
][ZZ
]-src
[ZZ
][XX
]*src
[XX
][ZZ
]);
322 dest
[YY
][ZZ
]=-c
*(src
[XX
][XX
]*src
[YY
][ZZ
]-src
[YY
][XX
]*src
[XX
][ZZ
]);
323 dest
[ZZ
][XX
]= c
*(src
[YY
][XX
]*src
[ZZ
][YY
]-src
[ZZ
][XX
]*src
[YY
][YY
]);
324 dest
[ZZ
][YY
]=-c
*(src
[XX
][XX
]*src
[ZZ
][YY
]-src
[ZZ
][XX
]*src
[XX
][YY
]);
325 dest
[ZZ
][ZZ
]= c
*(src
[XX
][XX
]*src
[YY
][YY
]-src
[YY
][XX
]*src
[XX
][YY
]);
328 static gmx_inline
void mvmul(matrix a
,rvec src
,rvec dest
)
330 dest
[XX
]=a
[XX
][XX
]*src
[XX
]+a
[XX
][YY
]*src
[YY
]+a
[XX
][ZZ
]*src
[ZZ
];
331 dest
[YY
]=a
[YY
][XX
]*src
[XX
]+a
[YY
][YY
]*src
[YY
]+a
[YY
][ZZ
]*src
[ZZ
];
332 dest
[ZZ
]=a
[ZZ
][XX
]*src
[XX
]+a
[ZZ
][YY
]*src
[YY
]+a
[ZZ
][ZZ
]*src
[ZZ
];
335 static gmx_inline
void unitv(rvec src
,rvec dest
)
339 linv
=invsqrt(iprod(src
,src
));
340 dest
[XX
]=linv
*src
[XX
];
341 dest
[YY
]=linv
*src
[YY
];
342 dest
[ZZ
]=linv
*src
[ZZ
];
345 static gmx_inline real
trace(matrix m
)
347 return (m
[XX
][XX
]+m
[YY
][YY
]+m
[ZZ
][ZZ
]);
350 static gmx_inline real
_divide(real a
,real b
,char *file
,int line
)
353 fatal_error(0,"Dividing by zero, file %s, line %d",file
,line
);
357 static gmx_inline
int _mod(int a
,int b
,char *file
,int line
)
360 fatal_error(0,"Modulo zero, file %s, line %d",file
,line
);
364 #define divide(a,b) _divide((a),(b),__FILE__,__LINE__)
365 #define mod(a,b) _mod((a),(b),__FILE__,__LINE__)