3
\brief Driver for second derivative integrals.
8
#include<libipv1/ip_lib.h>
10
#include<libciomr/libciomr.h>
11
#include<libpsio/psio.h>
12
#include<libint/libint.h>
13
#include<libiwl/iwl.h>
16
#include <Tools/prints.h>
23
#include"compute_scf_opdm.h"
24
#include"read_gen_opdm.h"
25
#include"enuc_deriv2.h"
27
#include"te_deriv2_scf.h"
35
//! Driver for integral second derivatives.
38
int i, j, ij, coord, ntri, natom, size;
40
double **tmpmat, **my_grad, *outbuf;
43
/*--- Hessian in the canonical frame ---*/
44
Hess = block_matrix(Molecule.num_atoms*3,Molecule.num_atoms*3);
46
/* Derivative Fock and overlap matrices */
47
F = (double ***) malloc(Molecule.num_atoms * 3 * sizeof(double **));
48
S = (double ***) malloc(Molecule.num_atoms * 3 * sizeof(double **));
49
HDS = (double ***) malloc(Molecule.num_atoms * 3 * sizeof(double **));
50
for(i=0; i < Molecule.num_atoms*3; i++) {
51
F[i] = block_matrix(BasisSet.num_ao, BasisSet.num_ao);
52
S[i] = block_matrix(BasisSet.num_ao, BasisSet.num_ao);
53
HDS[i] = block_matrix(BasisSet.num_ao, BasisSet.num_ao);
68
/* Multiply the F's by 2 -- accounts for orbital population factor */
69
for(coord=0; coord < Molecule.num_atoms*3; coord++) {
70
for(i=0; i < BasisSet.num_ao; i++)
71
for(j=0; j < BasisSet.num_ao; j++)
72
F[coord][i][j] *= 2.0;
77
/* te_deriv2_scf_symm(); */
80
/* divide the whole thing by 2 */
81
for(coord=0; coord < Molecule.num_atoms*3; coord++) {
82
for(i=0; i < BasisSet.num_ao; i++)
83
for(j=0; j < BasisSet.num_ao; j++)
84
F[coord][i][j] *= 0.5;
87
/* symmetrize the F's and S's */
88
for(coord=0; coord < Molecule.num_atoms*3; coord++) {
89
if (UserOptions.print_lvl >= PRINT_OEDERIV) {
90
fprintf(outfile, "AO-basis Overlap Derivs (Pre-Symm) (%d)", coord);
91
print_mat(S[coord],BasisSet.num_ao,BasisSet.num_ao,outfile);
94
for(i=0; i < BasisSet.num_ao; i++) {
95
for(j=0; j <= i; j++) {
97
F[coord][i][j] = F[coord][j][i] = 0.5 * (F[coord][i][j] + F[coord][j][i]);
98
S[coord][i][j] = S[coord][j][i] = 0.5 * (S[coord][i][j] + S[coord][j][i]);
103
if (UserOptions.print_lvl >= PRINT_OEDERIV) {
104
fprintf(outfile, "AO-basis Overlap Derivs (%d)", coord);
105
print_mat(S[coord],BasisSet.num_ao,BasisSet.num_ao,outfile);
109
/* Transform Fock and Overlap derivatives to the MO basis */
110
tmpmat = block_matrix(MOInfo.num_mo, BasisSet.num_ao);
111
for(i=0; i < Molecule.num_atoms*3; i++) {
112
C_DGEMM('n','n',MOInfo.num_mo,BasisSet.num_ao,BasisSet.num_ao,1.0,
113
&(MOInfo.scf_evec[0][0][0]),BasisSet.num_ao,&(F[i][0][0]),BasisSet.num_ao,
114
0.0,&(tmpmat[0][0]),BasisSet.num_ao);
115
C_DGEMM('n','t',MOInfo.num_mo,MOInfo.num_mo,BasisSet.num_ao,1.0,
116
&(tmpmat[0][0]),BasisSet.num_ao,&(MOInfo.scf_evec[0][0][0]),BasisSet.num_ao,
117
0.0,&(F[i][0][0]),BasisSet.num_ao);
119
C_DGEMM('n','n',MOInfo.num_mo,BasisSet.num_ao,BasisSet.num_ao,1.0,
120
&(MOInfo.scf_evec[0][0][0]),BasisSet.num_ao,&(S[i][0][0]),BasisSet.num_ao,
121
0.0,&(tmpmat[0][0]),BasisSet.num_ao);
122
C_DGEMM('n','t',MOInfo.num_mo,MOInfo.num_mo,BasisSet.num_ao,1.0,
123
&(tmpmat[0][0]),BasisSet.num_ao,&(MOInfo.scf_evec[0][0][0]),BasisSet.num_ao,
124
0.0,&(S[i][0][0]),BasisSet.num_ao);
128
/* write derivative Fock and overlap derivatives to disk */
129
ntri = MOInfo.num_mo * (MOInfo.num_mo + 1)/2;
130
outbuf = init_array(ntri);
131
label = (char *) malloc(PSIO_KEYLEN * sizeof(char));
132
for(i=0; i < PSIO_KEYLEN; i++) label[i] = '\0';
133
for(coord=0; coord < Molecule.num_atoms*3; coord++) {
135
for(i=0, ij=0; i < MOInfo.num_mo; i++) {
136
for(j=0; j <= i; j++, ij++) { /* Lower triangles only */
137
outbuf[ij] = F[coord][i][j];
141
sprintf(label, "MO-basis Fock Derivs (%d)", coord);
142
iwl_wrtone(PSIF_OEI, label, ntri, outbuf);
143
if (UserOptions.print_lvl >= PRINT_OEDERIV) {
144
fprintf(outfile," -%s\n",label);
145
print_mat(F[coord],MOInfo.num_mo,MOInfo.num_mo,outfile);
147
for(i=0; i < PSIO_KEYLEN; i++) label[i] = '\0';
149
for(coord=0; coord < Molecule.num_atoms*3; coord++) {
151
for(i=0, ij=0; i < MOInfo.num_mo; i++) {
152
for(j=0; j <= i; j++, ij++) { /* Lower triangles only */
153
outbuf[ij] = S[coord][i][j];
157
sprintf(label, "MO-basis Overlap Derivs (%d)", coord);
158
iwl_wrtone(PSIF_OEI, label, ntri, outbuf);
159
if (UserOptions.print_lvl >= PRINT_OEDERIV) {
160
fprintf(outfile," -%s\n",label);
161
print_mat(S[coord],MOInfo.num_mo,MOInfo.num_mo,outfile);
163
for(i=0; i < PSIO_KEYLEN; i++) label[i] = '\0';
165
/* Write half-differentiated overlap integrals to disk */
166
size = BasisSet.num_ao * BasisSet.num_ao;
167
for(coord=0; coord < Molecule.num_atoms*3; coord++) {
169
sprintf(label, "AO-basis Half-Diff Overlap (%d)", coord);
170
psio_open(PSIF_OEI, PSIO_OPEN_OLD);
171
psio_write_entry(PSIF_OEI, label, (char *) HDS[coord][0], size*sizeof(double));
172
psio_close(PSIF_OEI, 1);
173
if (UserOptions.print_lvl >= PRINT_OEDERIV) {
174
fprintf(outfile," -%s\n",label);
175
print_mat(HDS[coord],BasisSet.num_ao,BasisSet.num_ao,outfile);
177
for(i=0; i < PSIO_KEYLEN; i++) label[i] = '\0';
182
/* print_atommat("Skeleton contribution to the molecular Hessian (a.u.)",Hess); */
183
natom = Molecule.num_atoms;
184
psio_open(PSIF_DERINFO, PSIO_OPEN_NEW);
185
psio_write_entry(PSIF_DERINFO, "Skeleton Hessian", (char *) Hess[0], natom*3*natom*3*sizeof(double));
186
psio_close(PSIF_DERINFO, 1);
188
for(i=0; i < Molecule.num_atoms*3; i++) {
193
free(F); free(S); free(HDS);