Psi4
v3d.h
Go to the documentation of this file.
1 /*
2  * @BEGIN LICENSE
3  *
4  * Psi4: an open-source quantum chemistry software package
5  *
6  * Copyright (c) 2007-2017 The Psi4 Developers.
7  *
8  * The copyrights for code used from other parties are included in
9  * the corresponding files.
10  *
11  * This file is part of Psi4.
12  *
13  * Psi4 is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU Lesser General Public License as published by
15  * the Free Software Foundation, version 3.
16  *
17  * Psi4 is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public License along
23  * with Psi4; if not, write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25  *
26  * @END LICENSE
27  */
28 
34 #ifndef _opt_v3d_h_
35 #define _opt_v3d_h_
36 
37 #include "package.h"
38 
39 #if defined(OPTKING_PACKAGE_PSI)
40  #include <cmath>
41 #elif defined (OPTKING_PACKAGE_QCHEM)
42  #include "qcmath.h"
43 #endif
44 
45 #define V3D_SQR(x) ((x)*(x))
46 
47 #define PARALLEL_LIMIT (1.0e-10)
48 
49 namespace opt { namespace v3d {
50 
51 // scalar multiply a vector
52 inline void v3d_scm(const double a, double *A) {
53  A[0] *= a; A[1] *= a; A[2] *= a;
54 }
55 
56 // compute norm of a vector
57 inline double v3d_norm(const double *A) {
58  return sqrt(A[0]*A[0] + A[1]*A[1] + A[2]*A[2]);
59 }
60 
61 // take dot product of two vectors
62 inline double v3d_dot(const double *A, const double *B) {
63  return (A[0]*B[0] + A[1]*B[1] + A[2]*B[2]);
64 }
65 
66 // returns distance between 2 points
67 inline double v3d_dist(const double *A, const double *B) {
68  return sqrt(V3D_SQR(B[0]-A[0]) + V3D_SQR(B[1]-A[1]) + V3D_SQR(B[2]-A[2]));
69 }
70 
71 // Compute a*X + Y -> Z
72 inline void v3d_axpy(const double a, const double *X, const double *Y, double *Z) {
73  Z[0] = a*X[0] + Y[0];
74  Z[1] = a*X[1] + Y[1];
75  Z[2] = a*X[2] + Y[2];
76 }
77 
78 // normalize vector. Return "false and leave A unchanged if norm of A is
79 // less than min_norm or greater than max_norm
80 inline bool v3d_normalize(double *A, const double min_norm=1.0e-8, const double max_norm=1.0e8) {
81  double tval = v3d_norm(A);
82  if ( tval < min_norm || tval > max_norm)
83  return false;
84  else
85  v3d_scm(1.0/tval, A);
86  return true;
87 }
88 
89 // Compute cross product of two vectors
90 inline void v3d_cross_product(const double *u, const double *v, double *X) {
91  X[0] = u[1]*v[2]-u[2]*v[1];
92  X[1] = -1.0*(u[0]*v[2]-u[2]*v[0]);
93  X[2] = u[0]*v[1]-u[1]*v[0];
94  return;
95 }
96 
97 // check to see if two vectors are parallel, i.e., is |A.B| close to 1
98 inline bool v3d_is_parallel(const double *A, const double *B) {
99  if ( std::fabs( std::fabs(v3d_dot(A,B)) - 1.0e0) > PARALLEL_LIMIT )
100  return false;
101  else
102  return true;
103 }
104 
105 // Compute vector A->B. Normalize eAB. Return "false" and do not normalize
106 // eAB if points are too close or distant
107 inline bool v3d_eAB(const double *A, const double *B, double *eAB,
108 const double min_norm=1.0e-8, const double max_norm=1.0e15) {
109  v3d_axpy(-1, A, B, eAB);
110  return ( v3d_normalize(eAB, min_norm, max_norm) );
111 }
112 
113 // Computed angle in radians A-B-C (between vector B->A and vector B->C)
114 // if points are absurdly close or far apart, returns false
115 // tol is nearness of cos to 1/-1 to make angle 0/pi
116 bool v3d_angle(const double *A, const double *B, const double *C, double & phi, double tol=1e-14);
117 
118 // Computed torsional angle in radians A-B-C-D
119 // Returns false if bond angles ABC or BCD are too close to 0 or 180
120 bool v3d_tors(const double *A, const double *B, const double *C, const double *D, double & tau);
121 
122 // Computed out-of-plane angle in radians A-B-C-D for angle between A-B and C-B-D planes.
123 // Returns false if bond angles BCD is too close to 0 or 180
124 bool v3d_oofp(const double *A, const double *B, const double *C, const double *D,
125  double & oop_angle);
126 
127 }}
128 
129 #endif
void v3d_cross_product(const double *u, const double *v, double *X)
Definition: v3d.h:90
bool v3d_is_parallel(const double *A, const double *B)
Definition: v3d.h:98
double ** u
Definition: densgrid_RHF.cc:65
bool v3d_normalize(double *A, const double min_norm=1.0e-8, const double max_norm=1.0e8)
Definition: v3d.h:80
#define PARALLEL_LIMIT
Definition: v3d.h:47
bool v3d_eAB(const double *A, const double *B, double *eAB, const double min_norm=1.0e-8, const double max_norm=1.0e15)
Definition: v3d.h:107
#define V3D_SQR(x)
Definition: v3d.h:45
double v3d_dist(const double *A, const double *B)
Definition: v3d.h:67
double v3d_dot(const double *A, const double *B)
Definition: v3d.h:62
double v3d_norm(const double *A)
Definition: v3d.h:57
bool v3d_tors(const double *A, const double *B, const double *C, const double *D, double &tau)
Definition: v3d.cc:79
bool v3d_angle(const double *A, const double *B, const double *C, double &phi, double tol)
Definition: v3d.cc:45
void v3d_axpy(const double a, const double *X, const double *Y, double *Z)
Definition: v3d.h:72
bool v3d_oofp(const double *A, const double *B, const double *C, const double *D, double &oop_angle)
Definition: v3d.cc:127
void v3d_scm(const double a, double *A)
Definition: v3d.h:52