36
36
/* MAKE_DISP_IRREP - make displacements for modes labelled with
37
37
* symmetry IRREP (+ and - if symmetric; otherwise, just +) */
39
int make_disp_irrep(cartesians &carts, internals &simples, salc_set &all_salcs,
39
int make_disp_irrep(cartesians &carts, internals &simples, salc_set &all_salcs)
42
41
int i,j,a,b, cnt,dim, dim_carts, ndisps, nsalcs, *irrep_salcs, irrep;
43
43
double *fgeom, energy, **micro_geoms, **displacements;
44
44
double *f, *q, tval, **fgeom2D;
45
45
char *disp_label, **disp_irrep_lbls, *salc_lbl;
81
81
/*** make list of internal displacements for micro_iterations ***/
84
displacements = block_matrix(ndisps,all_salcs.get_num());
86
for (i=0; i<nsalcs; ++i) {
87
displacements[cnt++][irrep_salcs[i]] = -1.0 * optinfo.disp_size;
88
displacements[cnt++][irrep_salcs[i]] = 1.0 * optinfo.disp_size;
83
if (optinfo.points == 3) {
85
displacements = block_matrix(ndisps,all_salcs.get_num());
87
for (i=0; i<nsalcs; ++i) {
88
displacements[cnt++][irrep_salcs[i]] = -1.0 * optinfo.disp_size;
89
displacements[cnt++][irrep_salcs[i]] = 1.0 * optinfo.disp_size;
92
else if (optinfo.points == 5) {
94
displacements = block_matrix(ndisps,all_salcs.get_num());
96
for (i=0; i<nsalcs; ++i) {
97
displacements[cnt++][irrep_salcs[i]] = -2.0 * optinfo.disp_size;
98
displacements[cnt++][irrep_salcs[i]] = -1.0 * optinfo.disp_size;
99
displacements[cnt++][irrep_salcs[i]] = 1.0 * optinfo.disp_size;
100
displacements[cnt++][irrep_salcs[i]] = 2.0 * optinfo.disp_size;
91
104
else { // non-symmetric irrep
93
displacements = block_matrix(ndisps,all_salcs.get_num());
95
for (i=0; i<nsalcs; ++i)
96
displacements[cnt++][irrep_salcs[i]] = -1.0 * optinfo.disp_size;
105
if (optinfo.points == 3) {
107
displacements = block_matrix(ndisps,all_salcs.get_num());
109
for (i=0; i<nsalcs; ++i)
110
displacements[cnt++][irrep_salcs[i]] = -1.0 * optinfo.disp_size;
112
else if (optinfo.points == 5) {
114
displacements = block_matrix(ndisps,all_salcs.get_num());
116
for (i=0; i<nsalcs; ++i) {
117
displacements[cnt++][irrep_salcs[i]] = -2.0 * optinfo.disp_size;
118
displacements[cnt++][irrep_salcs[i]] = -1.0 * optinfo.disp_size;
99
// count number of unique displacements; 2 disps for symm modes
100
123
fprintf(outfile,"Generating a total of %d displacements ", ndisps);
101
fprintf(outfile,"using %d-point formula for modes of irrep %d.\n", points, irrep+1);
124
fprintf(outfile,"using %d-point formula for modes of irrep %d.\n",
125
optinfo.points, irrep+1);
103
127
fprintf(outfile,"\nDisplacement Matrix\n");
104
128
print_mat5(displacements, ndisps, all_salcs.get_num(), outfile);
120
144
psio_write_entry(PSIF_OPTKING, "OPT: Current disp_num",
121
145
(char *) &(optinfo.disp_num),sizeof(int));
123
psio_write_entry(PSIF_OPTKING, "OPT: Total num. of disp.",
147
psio_write_entry(PSIF_OPTKING, "OPT: Num. of disp.",
124
148
(char *) &(ndisps), sizeof(int));
127
150
free_block(micro_geoms);
129
152
// make room for storage of energy and gradients of displacements
132
155
disp_e = new double[ndisps];
133
156
disp_grad = new double [ndisps*3*carts.get_natom()*sizeof(double)];
136
157
psio_write_entry(PSIF_OPTKING, "OPT: Displaced gradients",
137
158
(char *) &(disp_grad[0]), ndisps*3*carts.get_natom()*sizeof(double));
139
159
psio_write_entry(PSIF_OPTKING, "OPT: Displaced energies",
140
160
(char *) &(disp_e[0]), ndisps*sizeof(double));
162
irrep_per_disp = init_int_array(ndisps);
163
for (i=0; i<ndisps; ++i) irrep_per_disp[i] = irrep;
164
psio_write_entry(PSIF_OPTKING, "OPT: Irrep per disp",
165
(char *) &(irrep_per_disp[0]), ndisps*sizeof(int));
166
free(irrep_per_disp);
145
170
// Reset microiteration counter
146
171
optinfo.micro_iteration = 0;
162
187
/* MAKE_DISP_NOSYMM generate displacements - do positive and
163
188
* negative displacements along all coordinates ignorning symmetry */
165
int make_disp_nosymm(cartesians &carts, internals &simples,
166
salc_set &all_salcs, int points)
190
int make_disp_nosymm(cartesians &carts, internals &simples, salc_set &all_salcs)
168
int i,j,a,b, dim, dim_carts, ndisps, nsalcs;
192
int i,j,a,b, dim, dim_carts, ndisps, nsalcs, *irrep_per_disp, cnt;
169
193
double *fgeom, energy, **micro_geoms, **displacements;
170
194
double *f, *q, tval, **fgeom2D;
171
char *disp_label, **disp_irrep_lbls;
195
char *disp_label, **disp_irrep_lbls, *lbl;
173
197
disp_label = new char[MAX_LINELENGTH];
174
198
dim_carts = 3*carts.get_natom();
176
200
nsalcs = all_salcs.get_num();
177
/* only 3-pt formula for now */
181
203
punt("There are no appropriate SALCs present to displace along.\n");
190
212
(char *) &(energy), sizeof(double));
215
/*** make list of internal displacements for micro_iterations ***/
216
if (optinfo.points == 3) {
218
displacements = block_matrix(ndisps, nsalcs);
219
for (i=0;i<all_salcs.get_num();++i) {
220
displacements[2*i][i] = -1.0 * optinfo.disp_size;
221
displacements[2*i+1][i] = 1.0 * optinfo.disp_size;
224
else if (optinfo.points == 5) {
226
displacements = block_matrix(ndisps, nsalcs);
227
for (i=0;i<all_salcs.get_num();++i) {
228
displacements[4*i+0][i] = -2.0 * optinfo.disp_size;
229
displacements[4*i+1][i] = -1.0 * optinfo.disp_size;
230
displacements[4*i+2][i] = 1.0 * optinfo.disp_size;
231
displacements[4*i+3][i] = 2.0 * optinfo.disp_size;
193
235
fprintf(outfile,"Generating a total of %d displacements ", ndisps);
194
fprintf(outfile,"using %d-point formula for all modes.\n", points);
196
/*** make list of internal displacements for micro_iterations ***/
197
displacements = block_matrix(ndisps, nsalcs);
198
for (i=0;i<all_salcs.get_num();++i) {
199
displacements[2*i][i] = -1.0 * optinfo.disp_size;
200
displacements[2*i+1][i] = 1.0 * optinfo.disp_size;
236
fprintf(outfile,"using %d-point formula for all modes.\n", optinfo.points);
204
238
fprintf(outfile,"\nDisplacement Matrix\n");
205
print_mat2(displacements, ndisps, nsalcs, outfile);
239
print_mat5(displacements, ndisps, nsalcs, outfile);
208
241
/*** generate and store Micro_iteration cartesian geometries ***/
209
242
micro_geoms = block_matrix(ndisps, dim_carts);
222
255
psio_write_entry(PSIF_OPTKING, "OPT: Current disp_num",
223
256
(char *) &(optinfo.disp_num),sizeof(int));
225
psio_write_entry(PSIF_OPTKING, "OPT: Total num. of disp.",
258
psio_write_entry(PSIF_OPTKING, "OPT: Num. of disp.",
226
259
(char *) &(ndisps), sizeof(int));
241
274
psio_write_entry(PSIF_OPTKING, "OPT: Displaced energies",
242
275
(char *) &(disp_e[0]), ndisps*sizeof(double));
277
irrep_per_disp = init_int_array(ndisps);
280
for (i=0; i<ndisps; ++i) {
281
lbl = all_salcs.get_label(i); /* returns pointer */
282
for (j=0; j<syminfo.nirreps; ++j) {
283
if ( strcmp( lbl, syminfo.irrep_lbls[j]) == 0) {
284
irrep_per_disp[++cnt] = j;
285
irrep_per_disp[++cnt] = j;
288
// lbl pointer is freed when all_salcs gets deleted
291
fprintf(outfile,"Irrep per displacement:\n");
292
for (i=0;i<ndisps;++i)
293
fprintf(outfile,"%3d",irrep_per_disp[i]);
294
fprintf(outfile,"\n");
296
psio_write_entry(PSIF_OPTKING, "OPT: Irrep per disp",
297
(char *) &(irrep_per_disp[0]), ndisps*sizeof(int));
298
free(irrep_per_disp);