Skip to content

Commit 9f91482

Browse files
committed
Check some Project 1 hints
1 parent f1539d0 commit 9f91482

File tree

8 files changed

+204
-0
lines changed

8 files changed

+204
-0
lines changed

Project#01/hints/hint4-1.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Note that, unlike the interatomic distance matrix and the three-dimensional bond angle array, the out-of-plane angles are not needed later in the program. Hence, there is no need to allocate any memory to store these angles. Simply print them one at a time.

Project#01/hints/hint4-2.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
A cross product between two vectors is another vector. Therefore, to store the cross product needed to compute a given out-of-plane angle, you need to store the x, y, and z components of the resulting vector, which you then use to compute a dot product with yet another vector. It is convenient to assign separate variables for each part of this calculation:
2+
```c++
3+
ejkl_x = (ey[k][j] * ez[k][l] - ez[k][j] * ey[k][l]);
4+
ejkl_y = (ez[k][j] * ex[k][l] - ex[k][j] * ez[k][l]);
5+
ejkl_z = (ex[k][j] * ey[k][l] - ey[k][j] * ex[k][l]);
6+
7+
exx = ejkl_x * ex[k][i];
8+
eyy = ejkl_y * ey[k][i];
9+
ezz = ejkl_z * ez[k][i];
10+
```

Project#01/hints/hint4-3.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
The final out-of-plane angle is computed using the `asin()` function. Note that since sine yields values between -1 and +1, the `asin()` function can only take arguments between -1.0 and +1.0. However, numerical precision in the calculation of the cross- and dot-products earlier in the calculation can yield results slightly outside this domain. Hence, you should test the argument of `asin()` before you call it:
2+
```c++
3+
theta = (exx + eyy + ezz)/sin(phi[j][k][l]);
4+
5+
if(theta < -1.0) theta = asin(-1.0);
6+
else if(theta > 1.0) theta = asin(1.0);
7+
else theta = asin(theta);
8+
```

Project#01/hints/hint4-4

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Just as for the bond angle code, we need to exclude ijkl combinations involving coincidences among the indices as well as distant atom pairs:
2+
```c++
3+
if(i!=j && i!=k && i!=l && j!=k && j!=l && k!=l) { } /* Skip coincidences */
4+
```
5+
and
6+
```c++
7+
if(R[i][k] < 4.0 && R[k][j] < 4.0 && R[k][l] < 4.0) { } /* Skip distant atom pairs */
8+
```

Project#01/hints/hint5-1.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Just as for the out-of-plane angles, there is no need to store the torsional angles after they are printed, so no special memory allocation procedure is needed for this step.

Project#01/hints/hint5-2.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Just as for `asin()` in the out-of-plane angle calculation, you should check the argument to `acos()` to make sure it lies between -1.0 and +1.0.

Project#01/hints/hint5-3.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
To print only the unique dihedral angles, it is straightforward in this case to limit the loop structure over i, j, k, and l to keep j < i, k < j, and l < k. Also, one should limit the printing only to atom pairs that are close together.

Project#01/hints/step4-solution.md

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
We've added a new function to the Molecule class for computing the out-of-plane angles. Here's the new molecule.h:
2+
3+
```c++
4+
#include <string>
5+
6+
using namespace std;
7+
8+
class Molecule
9+
{
10+
public:
11+
int natom;
12+
int charge;
13+
int *zvals;
14+
double **geom;
15+
string point_group;
16+
17+
void print_geom();
18+
void rotate(double phi);
19+
void translate(double x, double y, double z);
20+
double bond(int atom1, int atom2);
21+
double angle(int atom1, int atom2, int atom3);
22+
double torsion(int atom1, int atom2, int atom3, int atom4);
23+
double oop(int atom1, int atom2, int atom3, int atom4);
24+
double unit(int cart, int atom1, int atom2);
25+
26+
Molecule(const char *filename, int q);
27+
~Molecule();
28+
};
29+
```
30+
31+
Here's the new `oop()` function for molecule.cc:
32+
33+
```c++
34+
double Molecule::oop(int a, int b, int c, int d)
35+
{
36+
double ebcd_x = (unit(1,c,b) * unit(2,c,d) - unit(2,c,b) * unit(1,c,d));
37+
double ebcd_y = (unit(2,c,b) * unit(0,c,d) - unit(0,c,b) * unit(2,c,d));
38+
double ebcd_z = (unit(0,c,b) * unit(1,c,d) - unit(1,c,b) * unit(0,c,d));
39+
40+
double exx = ebcd_x * unit(0,c,a);
41+
double eyy = ebcd_y * unit(1,c,a);
42+
double ezz = ebcd_z * unit(2,c,a);
43+
44+
double theta = (exx + eyy + ezz)/sin(angle(b,c,d));
45+
46+
if(theta < -1.0) theta = asin(-1.0);
47+
else if(theta > 1.0) theta = asin(1.0);
48+
else theta = asin(theta);
49+
50+
return theta;
51+
}
52+
```
53+
54+
And finally the new code that makes use of the class:
55+
56+
```c++
57+
#include "molecule.h"
58+
#include <iostream>
59+
#include <fstream>
60+
#include <iomanip>
61+
#include <cstdio>
62+
#include <cmath>
63+
64+
using namespace std;
65+
66+
int main()
67+
{
68+
Molecule mol("geom.dat", 0);
69+
70+
cout << "Number of atoms: " << mol.natom << endl;
71+
cout << "Input Cartesian coordinates:\n";
72+
mol.print_geom();
73+
74+
cout << "Interatomic distances (bohr):\n";
75+
for(int i=0; i < mol.natom; i++)
76+
for(int j=0; j < i; j++)
77+
printf("%d %d %8.5f\n", i, j, mol.bond(i,j));
78+
79+
cout << "\nBond angles:\n";
80+
for(int i=0; i < mol.natom; i++) {
81+
for(int j=0; j < i; j++) {
82+
for(int k=0; k < j; k++) {
83+
if(mol.bond(i,j) < 4.0 && mol.bond(j,k) < 4.0)
84+
printf("%2d-%2d-%2d %10.6f\n", i, j, k, mol.angle(i,j,k)*(180.0/acos(-1.0)));
85+
}
86+
}
87+
}
88+
89+
cout << "\nOut-of-Plane angles:\n";
90+
for(int i=0; i < mol.natom; i++) {
91+
for(int k=0; k < mol.natom; k++) {
92+
for(int j=0; j < mol.natom; j++) {
93+
for(int l=0; l < j; l++) {
94+
if(i!=j && i!=k && i!=l && j!=k && k!=l && mol.bond(i,k) < 4.0 && mol.bond(k,j) < 4.0 && mol.bond(k,l) < 4.0)
95+
printf("%2d-%2d-%2d-%2d %10.6f\n", i, j, k, l, mol.oop(i,j,k,l)*(180.0/acos(-1.0)));
96+
}
97+
}
98+
}
99+
}
100+
101+
return 0;
102+
}
103+
```
104+
105+
The above code produces the following output for the acetaldehyde test case:
106+
107+
```
108+
Number of atoms: 7
109+
Input Cartesian coordinates:
110+
6 0.000000000000 0.000000000000 0.000000000000
111+
6 0.000000000000 0.000000000000 2.845112131228
112+
8 1.899115961744 0.000000000000 4.139062527233
113+
1 -1.894048308506 0.000000000000 3.747688672216
114+
1 1.942500819960 0.000000000000 -0.701145981971
115+
1 -1.007295466862 -1.669971842687 -0.705916966833
116+
1 -1.007295466862 1.669971842687 -0.705916966833
117+
Interatomic distances (bohr):
118+
1 0 2.84511
119+
2 0 4.55395
120+
2 1 2.29803
121+
3 0 4.19912
122+
3 1 2.09811
123+
3 2 3.81330
124+
4 0 2.06517
125+
4 1 4.04342
126+
4 2 4.84040
127+
4 3 5.87463
128+
5 0 2.07407
129+
5 1 4.05133
130+
5 2 5.89151
131+
5 3 4.83836
132+
5 4 3.38971
133+
6 0 2.07407
134+
6 1 4.05133
135+
6 2 5.89151
136+
6 3 4.83836
137+
6 4 3.38971
138+
6 5 3.33994
139+
140+
Bond angles:
141+
2- 1- 0 124.268308
142+
3- 1- 0 115.479341
143+
3- 2- 1 28.377448
144+
5- 4- 0 35.109529
145+
6- 4- 0 35.109529
146+
6- 5- 0 36.373677
147+
6- 5- 4 60.484476
148+
149+
Out-of-plane angles:
150+
0- 3- 1- 2 -0.000000
151+
0- 6- 4- 5 19.939726
152+
0- 6- 5- 4 -19.850523
153+
0- 5- 6- 4 19.850523
154+
1- 5- 0- 4 53.678778
155+
1- 6- 0- 4 -53.678778
156+
1- 6- 0- 5 54.977064
157+
2- 3- 1- 0 0.000000
158+
3- 2- 1- 0 -0.000000
159+
4- 5- 0- 1 -53.651534
160+
4- 6- 0- 1 53.651534
161+
4- 6- 0- 5 -54.869992
162+
4- 6- 5- 0 29.885677
163+
4- 5- 6- 0 -29.885677
164+
5- 4- 0- 1 53.626323
165+
5- 6- 0- 1 -56.277112
166+
5- 6- 0- 4 56.194621
167+
5- 6- 4- 0 -30.558964
168+
5- 4- 6- 0 31.064344
169+
6- 4- 0- 1 -53.626323
170+
6- 5- 0- 1 56.277112
171+
6- 5- 0- 4 -56.194621
172+
6- 5- 4- 0 30.558964
173+
6- 4- 5- 0 -31.064344
174+
```

0 commit comments

Comments
 (0)