3
\brief Enter brief description of file here
7
#include <libciomr/libciomr.h>
14
#include <physconst.h>
18
void alloc_irr_char();
19
void permute_axes(double **, int, int);
22
namespace psi { namespace input {
29
int **redun_atom_orbit; /*Redundant (i.e. for all 8 operations) atomic orbits*/
40
if (num_atoms == 1) { /* Atomic calculation */
41
/* symmetry = strdup("D2h ");
43
irr_labels = (char **) malloc(sizeof(char *)*nirreps);
44
sym_oper = init_int_array(nirreps);
46
irr_labels[0] = strdup("Ag ");
47
irr_labels[1] = strdup("B1g ");
48
irr_labels[2] = strdup("B2g ");
49
irr_labels[3] = strdup("B3g ");
50
irr_labels[4] = strdup("Au ");
51
irr_labels[5] = strdup("B1u ");
52
irr_labels[6] = strdup("B2u ");
53
irr_labels[7] = strdup("B3u ");
54
sym_oper[1] = C2ZFLAG;
55
sym_oper[2] = C2YFLAG;
56
sym_oper[3] = C2XFLAG;
58
sym_oper[5] = SIGXYFLAG;
59
sym_oper[6] = SIGXZFLAG;
60
sym_oper[7] = SIGYZFLAG;
61
atom_orbit = init_int_matrix(1,nirreps);
62
atom_orbit[0][0] = atom_orbit[0][1] = atom_orbit[0][2] = atom_orbit[0][3] = atom_orbit[0][4] =
63
atom_orbit[0][5] = atom_orbit[0][6] = atom_orbit[0][7] = 0;
68
redun_atom_orbit = init_int_matrix(num_atoms,8);
70
for(i=0;i<num_atoms;i++) {
71
if (c2x_flag && !redun_atom_orbit[i][C2XFLAG]) {
74
for(j=0;j<num_atoms;j++)
75
if ((int)nuclear_charges[i] == (int)nuclear_charges[j] && vect_equiv(geometry[j],v1)){
76
redun_atom_orbit[i][C2XFLAG] = j;
77
redun_atom_orbit[j][C2XFLAG] = i;
82
if (c2y_flag && !redun_atom_orbit[i][C2YFLAG]) {
85
for(j=0;j<num_atoms;j++)
86
if ((int)nuclear_charges[i] == (int)nuclear_charges[j] && vect_equiv(geometry[j],v1)){
87
redun_atom_orbit[i][C2YFLAG] = j;
88
redun_atom_orbit[j][C2YFLAG] = i;
93
if (c2z_flag && !redun_atom_orbit[i][C2ZFLAG]) {
96
for(j=0;j<num_atoms;j++)
97
if ((int)nuclear_charges[i] == (int)nuclear_charges[j] && vect_equiv(geometry[j],v1)){
98
redun_atom_orbit[i][C2ZFLAG] = j;
99
redun_atom_orbit[j][C2ZFLAG] = i;
104
if (inv_flag && !redun_atom_orbit[i][IFLAG]) {
105
inversion(geometry[i],v1);
107
for(j=0;j<num_atoms;j++)
108
if ((int)nuclear_charges[i] == (int)nuclear_charges[j] && vect_equiv(geometry[j],v1)){
109
redun_atom_orbit[i][IFLAG] = j;
110
redun_atom_orbit[j][IFLAG] = i;
115
if (sig_xy_flag && !redun_atom_orbit[i][SIGXYFLAG]) {
116
sig_xy(geometry[i],v1);
118
for(j=0;j<num_atoms;j++)
119
if ((int)nuclear_charges[i] == (int)nuclear_charges[j] && vect_equiv(geometry[j],v1)){
120
redun_atom_orbit[i][SIGXYFLAG] = j;
121
redun_atom_orbit[j][SIGXYFLAG] = i;
126
if (sig_xz_flag && !redun_atom_orbit[i][SIGXZFLAG]) {
127
sig_xz(geometry[i],v1);
129
for(j=0;j<num_atoms;j++)
130
if ((int)nuclear_charges[i] == (int)nuclear_charges[j] && vect_equiv(geometry[j],v1)){
131
redun_atom_orbit[i][SIGXZFLAG] = j;
132
redun_atom_orbit[j][SIGXZFLAG] = i;
137
if (sig_yz_flag && !redun_atom_orbit[i][SIGYZFLAG]) {
138
sig_yz(geometry[i],v1);
140
for(j=0;j<num_atoms;j++)
141
if ((int)nuclear_charges[i] == (int)nuclear_charges[j] && vect_equiv(geometry[j],v1)){
142
redun_atom_orbit[i][SIGYZFLAG] = j;
143
redun_atom_orbit[j][SIGYZFLAG] = i;
152
if (print_lvl >= DEBUGPRINT) {
153
fprintf(outfile,"\n -Symmetry flags:\n");
154
fprintf(outfile," C2x = %d\n",c2x_flag);
155
fprintf(outfile," C2y = %d\n",c2y_flag);
156
fprintf(outfile," C2z = %d\n",c2z_flag);
157
fprintf(outfile," I = %d\n",inv_flag);
158
fprintf(outfile," sxy = %d\n",sig_xy_flag);
159
fprintf(outfile," sxz = %d\n",sig_xz_flag);
160
fprintf(outfile," syz = %d\n",sig_yz_flag);
162
naxes = c2x_flag + c2y_flag + c2z_flag;
163
nplanes = sig_xy_flag + sig_xz_flag + sig_yz_flag;
164
nirreps = 1 + naxes + inv_flag + nplanes;
167
/*-------------------
169
--------------------*/
171
if (subgroup != NULL) {
173
case 8: /*Can be C2v, C2h, D2, etc.*/
174
if (!strcmp(subgroup,"D2")) {
175
nirreps = 4; nplanes = 0; inv_flag = 0;
176
sig_xy_flag = 0; sig_xz_flag = 0; sig_yz_flag = 0;
179
if (!strcmp(subgroup,"C2V")) {
180
if (unique_axis == NULL) {
181
printf(" UNIQUE_AXIS must be specified for this symmetry.\n The largest Abelian point group will be used.\n\n");
184
nirreps = 4; naxes = 1; nplanes = 2; inv_flag = 0;
185
if (!strcmp(unique_axis,"X")) {
186
c2y_flag = 0; c2z_flag = 0; sig_yz_flag = 0;
188
else if (!strcmp(unique_axis,"Y")) {
189
c2x_flag = 0; c2z_flag = 0; sig_xz_flag = 0;
191
else if (!strcmp(unique_axis,"Z")) {
192
c2x_flag = 0; c2y_flag = 0; sig_xy_flag = 0;
196
if (!strcmp(subgroup,"C2H")) {
197
if (unique_axis == NULL) {
198
printf(" UNIQUE_AXIS must be specified for this symmetry.\n The largest Abelian point group will be used.\n\n");
201
nirreps = 4; naxes = 1; nplanes = 1; inv_flag = 1;
202
if (!strcmp(unique_axis,"X")) {
203
c2y_flag = 0; c2z_flag = 0; sig_xy_flag = 0; sig_xz_flag = 0;
205
else if (!strcmp(unique_axis,"Y")) {
206
c2x_flag = 0; c2z_flag = 0; sig_xy_flag = 0; sig_yz_flag = 0;
208
else if (!strcmp(unique_axis,"Z")) {
209
c2x_flag = 0; c2y_flag = 0; sig_xz_flag = 0; sig_yz_flag = 0;
213
case 4: /*Can be C2, Cs, Ci, etc.*/
214
if (inv_flag && !strcmp(subgroup,"CI")) {
215
nirreps = 2; naxes = 0; nplanes = 0;
216
c2x_flag = 0; c2y_flag = 0; c2z_flag = 0;
217
sig_xy_flag = 0; sig_xz_flag = 0; sig_yz_flag = 0;
220
if ((naxes > 0) && !strcmp(subgroup,"C2")) {
222
if (unique_axis == NULL) {
223
printf(" UNIQUE_AXIS must be specified for this symmetry.\n The largest Abelian point group will be used.\n\n");
226
if (!strcmp(unique_axis,"X")) {
227
c2y_flag = 0; c2z_flag = 0;
229
else if (!strcmp(unique_axis,"Y")) {
230
c2x_flag = 0; c2z_flag = 0;
232
else if (!strcmp(unique_axis,"Z")) {
233
c2x_flag = 0; c2y_flag = 0;
237
nirreps = 2; nplanes = 0; inv_flag = 0;
238
sig_xy_flag = 0; sig_xz_flag = 0; sig_yz_flag = 0;
241
if ((nplanes > 0) && !strcmp(subgroup,"CS")) {
243
if (unique_axis == NULL) {
244
printf(" UNIQUE_AXIS must be specified for this symmetry.\n The largest Abelian point group will be used.\n\n");
247
if (!strcmp(unique_axis,"Z"))
249
sig_xz_flag = 0; sig_yz_flag = 0;
252
punt(" UNIQUE_AXIS defined incorrectly.");
253
else if (!strcmp(unique_axis,"Y"))
255
sig_xy_flag = 0; sig_yz_flag = 0;
258
punt(" UNIQUE_AXIS defined incorrectly.");
259
else if (!strcmp(unique_axis,"X"))
261
sig_xy_flag = 0; sig_xz_flag = 0;
264
punt(" UNIQUE_AXIS defined incorrectly.");
267
nirreps = 2; naxes = 0; inv_flag = 0;
268
c2x_flag = 0; c2y_flag = 0; c2z_flag = 0;
271
case 2: /*Can only be C1*/
272
if (!strcmp(subgroup,"C1")) {
273
nirreps = 1; naxes = 0; nplanes = 0;
274
c2x_flag = 0; c2y_flag = 0; c2z_flag = 0; inv_flag = 0;
275
sig_xy_flag = 0; sig_xz_flag = 0; sig_yz_flag = 0;
278
case 1: /*What subgroup???*/
279
if (strcmp(subgroup,"C1")) {
280
printf(" Subgroup specification doesn't comply with the actual symmetry.\n");
281
printf(" The largest Abelian point group will be used.\n\n");
285
if (print_lvl >= DEBUGPRINT) {
286
fprintf(outfile,"\n -Flags within the subgroup:\n");
287
fprintf(outfile," C2x = %d\n",c2x_flag);
288
fprintf(outfile," C2y = %d\n",c2y_flag);
289
fprintf(outfile," C2z = %d\n",c2z_flag);
290
fprintf(outfile," I = %d\n",inv_flag);
291
fprintf(outfile," sxy = %d\n",sig_xy_flag);
292
fprintf(outfile," sxz = %d\n",sig_xz_flag);
293
fprintf(outfile," syz = %d\n",sig_yz_flag);
298
/*-------------------------
299
Allocate character table
300
-------------------------*/
303
irr_labels = (char **) malloc(sizeof(char *)*nirreps);
306
/*---------------------------------------------------------------------
307
Figure out point group, reorient, if necessary, and get rid of zeros
308
in the array of atomic orbits
309
---------------------------------------------------------------------*/
311
atom_orbit = init_int_matrix(num_atoms,nirreps);
312
for(i=0;i<num_atoms;i++)
313
atom_orbit[i][EFLAG] = i;
314
sym_oper = init_int_array(nirreps);
317
case 1: /* There's one irreducible representation - it is C1 */
318
symmetry = strdup("C1 ");
319
irr_labels[0] = strdup("A ");
321
case 2: /* Could be Ci, C2, or Cs */
323
symmetry = strdup("Ci ");
324
irr_labels[0] = strdup("Ag ");
325
irr_labels[1] = strdup("Au ");
327
for(i=0;i<num_atoms;i++)
328
atom_orbit[i][1] = redun_atom_orbit[i][IFLAG]; /* i */
331
symmetry = strdup("C2 ");
332
irr_labels[0] = strdup("A ");
333
irr_labels[1] = strdup("B ");
334
sym_oper[1] = C2ZFLAG;
335
/* Making sure that the symmetry axis is along Z */
337
for(i=0;i<num_atoms;i++)
338
atom_orbit[i][1] = redun_atom_orbit[i][C2ZFLAG]; /* C2 = C2z */
340
if (c2x_flag) { /* Unique axis is along X */
341
permute_axes(geometry,XAXIS,ZAXIS);
342
for(i=0;i<num_atoms;i++) {
343
atom_orbit[i][1] = redun_atom_orbit[i][C2XFLAG]; /* C2 = C2x */
346
else { /* Unique axis is along Y */
347
permute_axes(geometry,YAXIS,ZAXIS);
348
for(i=0;i<num_atoms;i++) {
349
atom_orbit[i][1] = redun_atom_orbit[i][C2YFLAG]; /* C2 = C2y */
353
else if (nplanes) { /* Cs symmetry */
354
symmetry = strdup("Cs ");
355
irr_labels[0] = strdup("Ap ");
356
irr_labels[1] = strdup("App ");
357
sym_oper[1] = SIGXYFLAG;
359
for(i=0;i<num_atoms;i++)
360
atom_orbit[i][1] = redun_atom_orbit[i][SIGXYFLAG]; /* sig_xy */
362
if (sig_yz_flag) { /* Unique axis is along X */
363
permute_axes(geometry,XAXIS,ZAXIS);
364
for(i=0;i<num_atoms;i++) {
365
atom_orbit[i][1] = redun_atom_orbit[i][SIGYZFLAG]; /* sig_xy = sig_yz */
368
else { /* Unique axis is along Y */
369
permute_axes(geometry,YAXIS,ZAXIS);
370
for(i=0;i<num_atoms;i++) {
371
atom_orbit[i][1] = redun_atom_orbit[i][SIGXZFLAG]; /* sig_xy = sig_xz */
376
punt("Unidentified symmetry.");
379
case 4: /* It could be C2v, C2h, or D2 */
381
symmetry = strdup("C2h ");
382
/* Swap rows 1 and 2 in irr_char since ordering of irreps in C2h is different from that in C2v and D2*/
384
irr_char[1] = irr_char[2];
386
irr_labels[0] = strdup("Ag ");
387
irr_labels[1] = strdup("Bg ");
388
irr_labels[2] = strdup("Au ");
389
irr_labels[3] = strdup("Bu ");
390
sym_oper[1] = C2ZFLAG;
392
sym_oper[3] = SIGXYFLAG;
394
for(i=0;i<num_atoms;i++) {
395
atom_orbit[i][1] = redun_atom_orbit[i][C2ZFLAG]; /* C2 */
396
atom_orbit[i][2] = redun_atom_orbit[i][IFLAG]; /* i */
397
atom_orbit[i][3] = redun_atom_orbit[i][SIGXYFLAG]; /* sig_xy */
400
if (c2x_flag) { /* Unique axis is along X */
401
permute_axes(geometry,XAXIS,ZAXIS);
402
for(i=0;i<num_atoms;i++) {
403
atom_orbit[i][1] = redun_atom_orbit[i][C2XFLAG]; /* C2 = C2x */
404
atom_orbit[i][2] = redun_atom_orbit[i][IFLAG]; /* i */
405
atom_orbit[i][3] = redun_atom_orbit[i][SIGYZFLAG]; /* sig_xy = sig_yz */
408
else { /* Unique axis is along Y */
409
permute_axes(geometry,YAXIS,ZAXIS);
410
for(i=0;i<num_atoms;i++) {
411
atom_orbit[i][1] = redun_atom_orbit[i][C2YFLAG]; /* C2 = C2y */
412
atom_orbit[i][2] = redun_atom_orbit[i][IFLAG]; /* i */
413
atom_orbit[i][3] = redun_atom_orbit[i][SIGXZFLAG]; /* sig_xy = sig_xz */
417
else if (nplanes == 2) {
418
symmetry = strdup("C2v ");
419
irr_labels[0] = strdup("A1 ");
420
irr_labels[1] = strdup("A2 ");
421
irr_labels[2] = strdup("B1 ");
422
irr_labels[3] = strdup("B2 ");
423
sym_oper[1] = C2ZFLAG;
424
sym_oper[2] = SIGXZFLAG;
425
sym_oper[3] = SIGYZFLAG;
427
for(i=0;i<num_atoms;i++) {
428
atom_orbit[i][1] = redun_atom_orbit[i][C2ZFLAG]; /* C2 */
429
atom_orbit[i][2] = redun_atom_orbit[i][SIGXZFLAG]; /* sig_xz */
430
atom_orbit[i][3] = redun_atom_orbit[i][SIGYZFLAG]; /* sig_yz */
433
if (c2x_flag) { /* Unique axis is along X */
434
permute_axes(geometry,XAXIS,ZAXIS);
435
for(i=0;i<num_atoms;i++) {
436
atom_orbit[i][1] = redun_atom_orbit[i][C2XFLAG]; /* C2 = C2x */
437
atom_orbit[i][2] = redun_atom_orbit[i][SIGXYFLAG]; /* sig_xz = sig_yx */
438
atom_orbit[i][3] = redun_atom_orbit[i][SIGXZFLAG]; /* sig_yz = sig_zx */
441
else { /* Unique axis is along Y */
442
permute_axes(geometry,YAXIS,ZAXIS);
443
for(i=0;i<num_atoms;i++) {
444
atom_orbit[i][1] = redun_atom_orbit[i][C2YFLAG]; /* C2 = C2y */
445
atom_orbit[i][2] = redun_atom_orbit[i][SIGYZFLAG]; /* sig_xz = sig_zy */
446
atom_orbit[i][3] = redun_atom_orbit[i][SIGXYFLAG]; /* sig_yz = sig_xy */
450
else if (naxes == 3) { /* D2 symmetry */
451
symmetry = strdup("D2 ");
452
irr_labels[0] = strdup("A ");
453
irr_labels[1] = strdup("B1 ");
454
irr_labels[2] = strdup("B2 ");
455
irr_labels[3] = strdup("B3 ");
456
sym_oper[1] = C2ZFLAG;
457
sym_oper[2] = C2YFLAG;
458
sym_oper[3] = C2XFLAG;
459
for(i=0;i<num_atoms;i++) {
460
atom_orbit[i][1] = redun_atom_orbit[i][C2ZFLAG]; /* C2z */
461
atom_orbit[i][2] = redun_atom_orbit[i][C2YFLAG]; /* C2y */
462
atom_orbit[i][3] = redun_atom_orbit[i][C2XFLAG]; /* C2x */
466
punt("Unidentified symmetry.");
469
case 8: /* D2h symmetry */
470
if (nplanes == 3 && naxes == 3 && inv_flag) {
471
symmetry = strdup("D2h ");
472
irr_labels[0] = strdup("Ag ");
473
irr_labels[1] = strdup("B1g ");
474
irr_labels[2] = strdup("B2g ");
475
irr_labels[3] = strdup("B3g ");
476
irr_labels[4] = strdup("Au ");
477
irr_labels[5] = strdup("B1u ");
478
irr_labels[6] = strdup("B2u ");
479
irr_labels[7] = strdup("B3u ");
480
sym_oper[1] = C2ZFLAG;
481
sym_oper[2] = C2YFLAG;
482
sym_oper[3] = C2XFLAG;
484
sym_oper[5] = SIGXYFLAG;
485
sym_oper[6] = SIGXZFLAG;
486
sym_oper[7] = SIGYZFLAG;
487
for(i=0;i<num_atoms;i++) {
488
atom_orbit[i][1] = redun_atom_orbit[i][C2ZFLAG]; /* C2z */
489
atom_orbit[i][2] = redun_atom_orbit[i][C2YFLAG]; /* C2y */
490
atom_orbit[i][3] = redun_atom_orbit[i][C2XFLAG]; /* C2x */
491
atom_orbit[i][4] = redun_atom_orbit[i][IFLAG]; /* i */
492
atom_orbit[i][5] = redun_atom_orbit[i][SIGXYFLAG]; /* sig_xy */
493
atom_orbit[i][6] = redun_atom_orbit[i][SIGXZFLAG]; /* sig_xz */
494
atom_orbit[i][7] = redun_atom_orbit[i][SIGYZFLAG]; /* sig_yz */
498
punt("Unidentified symmetry.");
502
punt("Unidentified symmetry.");
503
} /* end of switch(nirreps) */
505
free_int_matrix(redun_atom_orbit);
510
}} // namespace psi::input
514
using namespace psi::input;
516
void alloc_irr_char()
520
/* Allocate global arrays */
521
irr_char = init_int_matrix(nirreps,nirreps);
523
for(i=0;i<nirreps;i++)
529
irr_char[1][0] = 1; irr_char[1][1] = -1;
532
irr_char[1][0] = 1; irr_char[1][1] = 1; irr_char[1][2] = -1; irr_char[1][3] = -1;
533
irr_char[2][0] = 1; irr_char[2][1] = -1; irr_char[2][2] = 1; irr_char[2][3] = -1;
534
irr_char[3][0] = 1; irr_char[3][1] = -1; irr_char[3][2] = -1; irr_char[3][3] = 1;
537
irr_char[1][0] = 1; irr_char[1][1] = 1; irr_char[1][2] = -1; irr_char[1][3] = -1;
538
irr_char[1][4] = 1; irr_char[1][5] = 1; irr_char[1][6] = -1; irr_char[1][7] = -1;
539
irr_char[2][0] = 1; irr_char[2][1] = -1; irr_char[2][2] = 1; irr_char[2][3] = -1;
540
irr_char[2][4] = 1; irr_char[2][5] = -1; irr_char[2][6] = 1; irr_char[2][7] = -1;
541
irr_char[3][0] = 1; irr_char[3][1] = -1; irr_char[3][2] = -1; irr_char[3][3] = 1;
542
irr_char[3][4] = 1; irr_char[3][5] = -1; irr_char[3][6] = -1; irr_char[3][7] = 1;
543
irr_char[4][0] = 1; irr_char[4][1] = 1; irr_char[4][2] = 1; irr_char[4][3] = 1;
544
irr_char[4][4] = -1; irr_char[4][5] = -1; irr_char[4][6] = -1; irr_char[4][7] = -1;
545
irr_char[5][0] = 1; irr_char[5][1] = 1; irr_char[5][2] = -1; irr_char[5][3] = -1;
546
irr_char[5][4] = -1; irr_char[5][5] = -1; irr_char[5][6] = 1; irr_char[5][7] = 1;
547
irr_char[6][0] = 1; irr_char[6][1] = -1; irr_char[6][2] = 1; irr_char[6][3] = -1;
548
irr_char[6][4] = -1; irr_char[6][5] = 1; irr_char[6][6] = -1; irr_char[6][7] = 1;
549
irr_char[7][0] = 1; irr_char[7][1] = -1; irr_char[7][2] = -1; irr_char[7][3] = 1;
550
irr_char[7][4] = -1; irr_char[7][5] = 1; irr_char[7][6] = 1; irr_char[7][7] = -1;
553
punt("Number of irreps in find_symmetry is invalid.");
559
/* This function permutes axes so that axis1 becomes axis2
560
This is done by a rotation about C3 axis relating x, y, and z
562
void permute_axes(double **geom, int axis1, int axis2)
567
double **R; /* The matrix representation of the forward rotation */
570
punt("Called permute_axes with axis1=axis2");
573
if ( (i != axis1) && (i != axis2)) {
578
R = block_matrix(3,3);
579
R[axis1][axis2] = 1.0;
580
R[axis2][axis3] = 1.0;
581
R[axis3][axis1] = 1.0;