source: ThirdParty/mpqc_open/src/lib/chemistry/qc/scf/scfgradient.cc@ a844d8

Candidate_v1.6.1
Last change on this file since a844d8 was 860145, checked in by Frederik Heber <heber@…>, 8 years ago

Merge commit '0b990dfaa8c6007a996d030163a25f7f5fc8a7e7' as 'ThirdParty/mpqc_open'

  • Property mode set to 100644
File size: 6.0 KB
Line 
1//
2// scfgradient.cc --- implementation of SCF::compute_gradient
3//
4// Copyright (C) 1996 Limit Point Systems, Inc.
5//
6// Author: Edward Seidl <seidl@janed.com>
7// Maintainer: LPS
8//
9// This file is part of the SC Toolkit.
10//
11// The SC Toolkit is free software; you can redistribute it and/or modify
12// it under the terms of the GNU Library General Public License as published by
13// the Free Software Foundation; either version 2, or (at your option)
14// any later version.
15//
16// The SC Toolkit is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU Library General Public License for more details.
20//
21// You should have received a copy of the GNU Library General Public License
22// along with the SC Toolkit; see the file COPYING.LIB. If not, write to
23// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24//
25// The U.S. Government is granted a limited license as per AL 91-7.
26//
27
28#include <iostream>
29
30#include <stdexcept>
31
32#include <util/misc/timer.h>
33#include <util/misc/formio.h>
34
35#include <math/scmat/offset.h>
36#include <math/scmat/local.h>
37
38#include <chemistry/qc/basis/obint.h>
39
40#include <chemistry/qc/scf/scf.h>
41#include <chemistry/qc/scf/scflocal.h>
42
43using namespace sc;
44
45//////////////////////////////////////////////////////////////////////////////
46
47static void
48ob_gradient(const Ref<OneBodyDerivInt>& derint, double * gradient,
49 const RefSymmSCMatrix& density, const Ref<GaussianBasisSet>& gbs_,
50 const Ref<MessageGrp>& grp)
51{
52 int gsh=0;
53
54 GaussianBasisSet& gbs = *gbs_.pointer();
55 Molecule& mol = *gbs_->molecule().pointer();
56
57 Ref<SCMatrixSubblockIter> diter =
58 density->local_blocks(SCMatrixSubblockIter::Read);
59
60 for (diter->begin(); diter->ready(); diter->next()) {
61 SCMatrixBlock *dblk = diter->block();
62 double *ddata;
63 int istart, iend;
64 int jstart, jend;
65 int sub=0;
66
67 ddata = get_tri_block(dblk, istart, iend, jstart, jend, sub);
68 if (!ddata) {
69 ExEnv::errn() << indent <<
70 "ob_gradient: can't figure out what density block is\n";
71 abort();
72 }
73
74 if (istart >= iend || jstart >= jend)
75 continue;
76
77 int ishstart = gbs.function_to_shell(istart);
78 int ishend = (iend) ? gbs.function_to_shell(iend-1) : 0;
79
80 int jshstart = gbs.function_to_shell(jstart);
81 int jshend = (jend) ? gbs.function_to_shell(jend-1) : 0;
82
83 for (int ish=ishstart; ish <= ishend; ish++) {
84 GaussianShell& gsi = gbs(ish);
85
86 int ist = gbs.shell_to_function(ish);
87 int ien = ist + gsi.nfunction();
88
89 for (int jsh=jshstart; jsh <= jshend; jsh++, gsh++) {
90 if (jsh > ish)
91 break;
92
93 GaussianShell& gsj = gbs(jsh);
94
95 int jst = gbs.shell_to_function(jsh);
96 int jen = jst + gsj.nfunction();
97
98 for (int x=0; x < mol.natom(); x++) {
99 derint->compute_shell(ish,jsh,x);
100 const double *buf = derint->buffer();
101
102 int index=0;
103 double dx=0, dy=0, dz=0;
104 for (int i=ist; i < ien; i++) {
105 for (int j=jst; j < jen; j++) {
106 if (i < istart || i >= iend || j < jstart || j >= jend
107 || j > i) {
108 index += 3;
109 } else {
110 int doff = (sub) ? ij_offset(i,j) :
111 ij_offset(i-istart,j-jstart);
112 double denij = ddata[doff];
113 if (j!=i) denij *= 2.0;
114 dx += buf[index++] * denij;
115 dy += buf[index++] * denij;
116 dz += buf[index++] * denij;
117 }
118 }
119 }
120
121 gradient[x*3+0] += dx;
122 gradient[x*3+1] += dy;
123 gradient[x*3+2] += dz;
124 }
125 }
126 }
127 }
128}
129
130//////////////////////////////////////////////////////////////////////////////
131
132void
133SCF::compute_gradient(const RefSCVector& gradient)
134{
135 tim_enter("compute gradient");
136 int i;
137
138 init_gradient();
139
140 int n3=gradient.n();
141
142 if (atom_basis().nonnull()) {
143 throw std::runtime_error("SCF::compute_gradient: atom_basis not supported");
144 }
145
146 // do the nuclear contribution
147 tim_enter("nuc rep");
148
149 double *g = new double[n3];
150 nuclear_repulsion_energy_gradient(g);
151
152 if (debug_) {
153 gradient.assign(g);
154 print_natom_3(gradient,"Nuclear Contribution to the Gradient:");
155 }
156
157 double *o = new double[n3];
158 memset(o,0,sizeof(double)*gradient.n());
159
160 // form overlap contribution
161 tim_change("overlap gradient");
162 RefSymmSCMatrix dens = lagrangian();
163 Ref<OneBodyDerivInt> derint = integral()->overlap_deriv();
164 ob_gradient(derint, o, dens, basis(), scf_grp_);
165
166 scf_grp_->sum(o,n3);
167
168 if (debug_) {
169 gradient.assign(o);
170 print_natom_3(gradient,"Overlap Contribution to the Gradient:");
171 }
172
173 for (i=0; i < n3; i++) g[i] += o[i];
174
175 // other one electron contributions
176 tim_change("one electron gradient");
177 memset(o,0,sizeof(double)*gradient.n());
178 dens = gradient_density();
179 derint = integral()->hcore_deriv();
180 ob_gradient(derint, o, dens, basis(), scf_grp_);
181
182 scf_grp_->sum(o,n3);
183
184 if (debug_) {
185 gradient.assign(o);
186 print_natom_3(gradient,"One-Electron Contribution to the Gradient:");
187 }
188
189 for (i=0; i < n3; i++) g[i] += o[i];
190
191 dens=0;
192 derint=0;
193
194 // now calculate two electron contribution
195 tim_change("two electron gradient");
196 memset(o,0,sizeof(double)*gradient.n());
197 two_body_deriv(o);
198 tim_exit("two electron gradient");
199
200 if (debug_) {
201 gradient.assign(o);
202 print_natom_3(gradient,"Two-Electron Contribution to the Gradient:");
203 }
204
205 for (i=0; i < n3; i++) g[i] += o[i];
206
207 gradient.assign(g);
208 delete[] g;
209 delete[] o;
210
211 if (debug_) {
212 print_natom_3(gradient,"Total Gradient:");
213 }
214
215 done_gradient();
216 tim_exit("compute gradient");
217 //tim_print(0);
218}
219
220//////////////////////////////////////////////////////////////////////////////
221
222void
223SCF::compute_hessian(const RefSymmSCMatrix& hessian)
224{
225}
226
227/////////////////////////////////////////////////////////////////////////////
228
229// Local Variables:
230// mode: c++
231// c-file-style: "ETS"
232// End:
Note: See TracBrowser for help on using the repository browser.