2
** CPHF: Program to solve the Coupled Perturbed Hartree-Fock equations
3
** for nuclear and electric field perturbations and to compute
4
** electric polarizabilities, harmonic vibrational frequencies, and IR
7
** Limitations of and future plans for this code:
9
** (1) Spin-restricted closed-shell Hartree-Fock (RHF) wave functions
10
** only. Extension to ROHF and UHF cases is needed.
12
** (2) All two-electron integrals are held in core and used in the MO
13
** basis. Out-of-core and AO-based algorithms are needed in mohess.c,
14
** cphf_X.c, and build_hessian.c in order to handle larger basis sets
15
** and to avoid the two-electron integral transformation.
17
** (3) Symmetry-blocking is used in most of the loops, but is not
18
** actually used to improve storage or computational order. I've put
19
** this off because the nuclear perturbations (x, y, and z on each
20
** nucleus) are not yet symmetry-adapted. Some effort in this area is
23
** (4) Thermodynamic functions, including enthalpies, entropies, heat
24
** capacities, free energies, and partition functions can be computed,
25
** given the vibrational data computed in vibration.c.
27
** TDC, December 2001 and October 2002
33
#include <libipv1/ip_lib.h>
34
#include <libciomr/libciomr.h>
35
#include <libpsio/psio.h>
36
#include <libiwl/iwl.h>
37
#include <libchkpt/chkpt.h>
42
void init_io(int argc, char *argv[]);
50
void out_of_core(double ***, double ***, double ***, double **);
51
void sort_B(double ***, double **);
52
void sort_A(double **, double **);
53
void mohess(double **);
54
void cphf_X(double ***, double **, double **, double ***);
55
void cphf_F(double **, double ***);
56
void polarize(double ***);
57
void build_hessian(double ***, double ***, double **, double ***, double **);
58
void build_dipder(double ***, double **);
59
void vibration(double **, double **);
61
int main(int argc, char *argv[])
81
timer_on("CPHF Main");
84
errcod = ip_data("PRINT", "%d", &(print_lvl), 0);
88
F = (double ***) malloc(natom*3 * sizeof(double **));
89
S = (double ***) malloc(natom*3 * sizeof(double **));
90
B = (double ***) malloc(natom*3 * sizeof(double **));
91
for(coord=0; coord < natom*3; coord++) {
92
F[coord] = block_matrix(nmo, nmo);
93
S[coord] = block_matrix(nmo, nmo);
94
B[coord] = block_matrix(nmo, nmo);
97
A = block_matrix(num_pq,num_pq);
99
out_of_core(F, S, B, A);
101
Baijk = block_matrix(natom*3, num_ai);
105
for(coord=0; coord < natom*3; coord++) {
106
free_block(B[coord]);
110
Aaibj = block_matrix(num_ai,num_ai);
116
UX = (double ***) malloc(natom*3 * sizeof(double **));
117
for(coord=0; coord < natom*3; coord++) {
118
UX[coord] = block_matrix(nmo,nmo);
121
cphf_X(S, Baijk, Aaibj, UX);
123
UF = (double ***) malloc(3 * sizeof(double **));
124
for(coord=0; coord < 3; coord++) {
125
UF[coord] = block_matrix(nmo,nmo);
132
hessian = block_matrix(natom*3, natom*3);
133
build_hessian(F, S, A, UX, hessian);
135
dipder = block_matrix(3, natom*3);
136
build_dipder(UX, dipder);
138
vibration(hessian, dipder);
146
for(coord=0; coord < natom*3; coord++) {
147
free_block(UX[coord]);
148
free_block(F[coord]);
149
free_block(S[coord]);
151
for(coord=0; coord < 3; coord++) {
152
free_block(UF[coord]);
154
free(UX); free(UF); free(F); free(S);
158
timer_off("CPHF Main");
162
exit(PSI_RETURN_SUCCESS);
165
void init_io(int argc, char *argv[])
167
extern char *gprgid(void);
170
progid = (char *) malloc(strlen(gprgid())+2);
171
sprintf(progid, ":%s",gprgid());
173
psi_start(argc-1,argv+1,0);
183
fprintf(outfile, "\t\t\t**************************\n");
184
fprintf(outfile, "\t\t\t* *\n");
185
fprintf(outfile, "\t\t\t* CPHF *\n");
186
fprintf(outfile, "\t\t\t* *\n");
187
fprintf(outfile, "\t\t\t**************************\n");
200
char *prgid = "CPHF";
208
ioff = (int *) malloc(IOFF_MAX * sizeof(int));
210
for(i=1; i < IOFF_MAX; i++) {
211
ioff[i] = ioff[i-1] + i;