1
/*** cartesians.cc : contains member functions for cartesian class ***/
13
#include <libciomr/libciomr.h>
14
#include <libipv1/ip_lib.h>
15
#include <libchkpt/chkpt.h>
16
#include <physconst.h>
22
#include "cartesians.h"
26
/*** FORCES returns forces in cartesian coordinates in aJ/Ang ***/
27
double *cartesians:: get_forces() {
30
f = init_array(3*natom);
31
for (i=0;i<3*natom;++i)
32
f[i] = -1.0 * grad[i] * _hartree2J * 1.0E18 / _bohr2angstroms;
36
double *cartesians:: get_fforces() {
39
f = init_array(3*nallatom);
40
for (i=0; i<3*nallatom; ++i) {
41
f[i] = -1.0 * fgrad[i] * _hartree2J * 1.0E18 / _bohr2angstroms;
47
/*** CARTESIANS this is the class constructor for cartesian ***/
48
cartesians::cartesians() {
49
int i, j, a, count, isotopes_given = 0, masses_given = 0;
50
char label[MAX_LINELENGTH], line1[MAX_LINELENGTH];
52
double an,x,y,z,tval,tval1,tval2,tval3,tval4;
53
double **geom, **fgeom, *zvals;
55
natom = optinfo.natom;
56
nallatom = optinfo.nallatom;
58
/* All data (but maybe masses) now read from chkpt */
59
chkpt_init(PSIO_OPEN_OLD);
60
geom = chkpt_rd_geom();
61
fgeom = chkpt_rd_fgeom();
63
if ((optinfo.mode == MODE_OPT_STEP) || (optinfo.mode == MODE_GRAD_SAVE))
64
grad = chkpt_rd_grad();
65
else grad = init_array(3*natom);
67
if ((optinfo.mode == MODE_OPT_STEP) || (optinfo.mode == MODE_ENERGY_SAVE)
68
||(optinfo.mode == MODE_DISP_NOSYMM) || (optinfo.mode == MODE_DISP_IRREP)
69
||(optinfo.mode == MODE_DISP_LOAD) || (optinfo.mode == MODE_DISP_USER))
70
energy = chkpt_rd_etot();
72
zvals = chkpt_rd_zvals();
75
coord = new double[3*natom];
76
atomic_num = new double[natom];
77
mass = new double[3*natom];
78
fcoord = new double[3*nallatom];
79
fgrad = new double[3*nallatom];
80
fatomic_num = new double[nallatom];
81
fmass = new double[3*nallatom];
84
for(i=0; i < natom; i++) {
85
atomic_num[i] = zvals[i];
86
for(j=0; j < 3; j++) {
87
coord[++count] = geom[i][j];
92
zero_arr(fatomic_num,nallatom);
93
for(i=0; i<natom; i++)
94
fatomic_num[optinfo.to_dummy[i]] = zvals[i];
97
for(i=0; i<nallatom; i++)
99
fcoord[++count] = fgeom[i][j];
104
zero_arr(fgrad, 3*nallatom);
106
for(i=0; i < natom; i++)
108
fgrad[3*optinfo.to_dummy[i]+j] = grad[3*i+j];
110
/* read masses from input.dat or use default masses */
113
if (ip_exist("ISOTOPES",0)) {
116
ip_count("ISOTOPES", &a, 0);
118
fprintf(outfile,"ISOTOPES array has wrong dimension.\n");
121
for (i=0;i<natom;++i) {
122
ip_data("ISOTOPES","%s", line1,1,i);
123
for (j=0;j<138;j++) {
124
if (strcmp(line1, mass_labels[j]) == 0) {
125
mass[++count] = atomic_masses[j];
126
mass[++count] = atomic_masses[j];
127
mass[++count] = atomic_masses[j];
133
"Isotope label %s is unidentifiable.\n",mass_labels[j]);
138
if (ip_exist("MASSES",0)) {
141
fprintf(outfile,"Ignoring ISOTOPES keyword, using given MASSES.\n");
143
ip_count("MASSES",&a,0);
145
fprintf(outfile,"MASSES array has wrong dimension\n");
149
for(i=0;i<natom;++i) {
150
ip_data("MASSES","%lf",&tval,1,i);
151
mass[++count] = tval;
152
mass[++count] = tval;
153
mass[++count] = tval;
157
if ((isotopes_given == 0) && (masses_given == 0)) {
158
for(i=0;i<natom;++i) {
159
a = (int) get_atomic_num(i); // casting to an int for index
160
mass[++count] = an2masses[a];
161
mass[++count] = an2masses[a];
162
mass[++count] = an2masses[a];
166
zero_arr(fmass, 3*nallatom);
167
for (i=0; i<natom; ++i) {
168
j = optinfo.to_dummy[i];
169
fmass[3*j+0] = fmass[3*j+1] = fmass[3*j+2] = mass[3*i];
173
fprintf(outfile,"masses without dummy atoms\n");
174
for (i=0; i<nallatom; ++i)
175
fprintf(outfile,"%15.10lf%15.10lf%15.10lf\n",
176
fmass[3*i],fmass[3*i+1],fmass[3*i+2]);
182
/*** CARTESIANS::PRINT
185
* 1 fatomic_num, fcoord fp_out
186
* 2 fatomic_num, fmass, fcoord fp_out
187
* 3 fatomic_num, fmass, fcoord, fgrad fp_out
189
* 5 atomic_num, coord fp_out
190
* 6 atomic_num, mass, coord fp_out
191
* 7 atomic_num, mass, coord, grad fp_out
193
* 11 coord, grad file11.dat
194
* 32 fcoord (implicitly coord) chkpt
195
* 12 fatomic_symb, fcoord fp_out
196
* disp_label is only used for geom.dat writing ***/
198
void cartesians :: print(int print_flag, FILE *fp_out, int new_geom_file,
199
char *disp_label, int disp_num) {
205
if (print_flag == 0) {
206
for (i = 0; i < natom; ++i) {
207
x = coord[++cnt]; y = coord[++cnt]; z = coord[++cnt];
208
fprintf(fp_out,"%20.10f%20.10f%20.10f\n",x,y,z);
211
else if (print_flag == 1) {
212
for (i = 0; i < natom; ++i) {
213
x = coord[++cnt]; y = coord[++cnt]; z = coord[++cnt];
214
fprintf(fp_out,"%5.1lf%15.10f%15.10f%15.10f\n",atomic_num[i],x,y,z);
217
else if (print_flag == 2) {
219
for (i = 0; i < natom; ++i) {
220
x = coord[++cnt]; y = coord[++cnt]; z = coord[++cnt];
222
"%5.1lf%15.8lf%15.10f%15.10f%15.10f\n",atomic_num[i],mass[3*i],x,y,z);
225
else if (print_flag == 3) {
227
for (i = 0; i < natom; ++i) {
228
x = coord[++cnt]; y = coord[++cnt]; z = coord[++cnt];
230
"%5.1lf%15.8lf%15.10f%15.10f%15.10f\n",atomic_num[i],mass[3*i],x,y,z);
233
for (i = 0; i < natom; ++i) {
234
x = grad[++cnt]; y = grad[++cnt]; z = grad[++cnt];
236
"%35.10lf%15.10f%15.10f\n",x,y,z);
239
if (print_flag == 4) {
240
for (i = 0; i < natom; ++i) {
241
x = coord[++cnt]; y = coord[++cnt]; z = coord[++cnt];
242
fprintf(fp_out,"%20.10f%20.10f%20.10f\n",x,y,z);
245
else if (print_flag == 5) {
246
for (i = 0; i < natom; ++i) {
247
x = coord[++cnt]; y = coord[++cnt]; z = coord[++cnt];
248
fprintf(fp_out,"%5.1lf%15.10f%15.10f%15.10f\n",atomic_num[i],x,y,z);
251
else if (print_flag == 6) {
253
for (i = 0; i < natom; ++i) {
254
x = coord[++cnt]; y = coord[++cnt]; z = coord[++cnt];
256
"%5.1lf%15.8lf%15.10f%15.10f%15.10f\n",atomic_num[i],mass[3*i],x,y,z);
259
else if (print_flag == 7) {
261
for (i = 0; i < natom; ++i) {
262
x = coord[++cnt]; y = coord[++cnt]; z = coord[++cnt];
264
"%5.1lf%15.8lf%15.10f%15.10f%15.10f\n",atomic_num[i],mass[3*i],x,y,z);
267
for (i = 0; i < natom; ++i) {
268
x = grad[++cnt]; y = grad[++cnt]; z = grad[++cnt];
270
"%35.10lf%15.10f%15.10f\n",x,y,z);
273
else if (print_flag == 10) {
274
//if (new_geom_file) fprintf(fp_out,"%%%%\n");
275
fprintf(fp_out,"%% %s\n",disp_label);
276
fprintf(fp_out,"geometry%1d = (\n", disp_num);
278
for (i=0; i<natom; ++i) {
279
x = coord[++cnt]; y = coord[++cnt]; z = coord[++cnt];
280
fprintf(fp_out,"(%20.10f%20.10f%20.10f)\n",x,y,z);
282
fprintf(fp_out," )\n");
284
else if (print_flag == 11) {
285
fprintf(fp_out,"%s\n",disp_label);
286
fprintf(fp_out,"%5d%20.10lf\n",natom,energy);
288
for (i = 0; i < natom; ++i) {
289
x = coord[++cnt]; y = coord[++cnt]; z = coord[++cnt];
291
"%20.10lf%20.10lf%20.10lf%20.10lf\n",atomic_num[i],x,y,z);
294
for (i = 0; i < natom; ++i) {
295
x = grad[++cnt]; y = grad[++cnt]; z = grad[++cnt];
296
fprintf(fp_out,"%40.10lf%20.10lf%20.10lf\n",x,y,z);
299
else if (print_flag == 32) {
301
fprintf(outfile,"\nGeometry written to chkpt\n");
304
geom = block_matrix(nallatom,3);
305
for (i=0; i<nallatom; ++i)
307
geom[optinfo.to_dummy[i]][j] = coord[3*i+j];
308
chkpt_init(PSIO_OPEN_OLD);
309
chkpt_wt_fgeom(geom);
315
chkpt_init(PSIO_OPEN_OLD);
316
tmp2d = chkpt_rd_fgeom();
318
for (i=0; i<nallatom; ++i)
320
fprintf(outfile,"%15.10lf\n", tmp2d[i][j]);
325
else if (print_flag == 12) {
326
for (i = 0; i < natom; ++i) {
327
x = coord[++cnt]; y = coord[++cnt]; z = coord[++cnt];
328
zval_to_symbol(atomic_num[i],sym);
329
fprintf(fp_out," (%3s%15.10f%15.10f%15.10f )\n",sym,x,y,z);