1 | //
|
---|
2 | // density.h
|
---|
3 | //
|
---|
4 | // Copyright (C) 1996 Limit Point Systems, Inc.
|
---|
5 | //
|
---|
6 | // Author: Curtis Janssen <cljanss@limitpt.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 | #ifndef _chemistry_qc_wfn_density_h
|
---|
29 | #define _chemistry_qc_wfn_density_h
|
---|
30 |
|
---|
31 | #ifdef __GNUC__
|
---|
32 | #pragma interface
|
---|
33 | #endif
|
---|
34 |
|
---|
35 | #include <math/isosurf/volume.h>
|
---|
36 | #include <chemistry/qc/wfn/wfn.h>
|
---|
37 | #include <chemistry/qc/basis/extent.h>
|
---|
38 | #include <chemistry/molecule/molrender.h>
|
---|
39 |
|
---|
40 | namespace sc {
|
---|
41 |
|
---|
42 | /** This is a Volume that computer the electron density. It
|
---|
43 | can be used to generate isodensity surfaces. */
|
---|
44 | class ElectronDensity: public Volume {
|
---|
45 | protected:
|
---|
46 | Ref<Wavefunction> wfn_;
|
---|
47 | virtual void compute();
|
---|
48 | public:
|
---|
49 | ElectronDensity(const Ref<KeyVal>&);
|
---|
50 | ElectronDensity(const Ref<Wavefunction>&);
|
---|
51 | ~ElectronDensity();
|
---|
52 | virtual void boundingbox(double valuemin,
|
---|
53 | double valuemax,
|
---|
54 | SCVector3& p1, SCVector3& p2);
|
---|
55 | };
|
---|
56 |
|
---|
57 | /** This a more highly optimized than ElectronDensity since
|
---|
58 | everything is precomputed. However, it cannot be used
|
---|
59 | if the density and/or geometry might change between
|
---|
60 | computations of the density or bounding box, unless the
|
---|
61 | obsolete member is called. */
|
---|
62 | class BatchElectronDensity: public Volume {
|
---|
63 | void zero_pointers();
|
---|
64 | protected:
|
---|
65 | Ref<Wavefunction> wfn_;
|
---|
66 |
|
---|
67 | Ref<GaussianBasisSet> basis_;
|
---|
68 |
|
---|
69 | // shared between threads
|
---|
70 | double *alpha_dmat_;
|
---|
71 | double *beta_dmat_;
|
---|
72 | double *dmat_bound_;
|
---|
73 | ShellExtent *extent_;
|
---|
74 |
|
---|
75 | // private data
|
---|
76 | GaussianBasisSet::ValueData *valdat_;
|
---|
77 | int ncontrib_;
|
---|
78 | int *contrib_;
|
---|
79 | int ncontrib_bf_;
|
---|
80 | int *contrib_bf_;
|
---|
81 | double *bs_values_;
|
---|
82 | double *bsg_values_;
|
---|
83 | double *bsh_values_;
|
---|
84 |
|
---|
85 | int nshell_;
|
---|
86 | int nbasis_;
|
---|
87 | int spin_polarized_;
|
---|
88 | int linear_scaling_;
|
---|
89 | int use_dmat_bound_;
|
---|
90 |
|
---|
91 | bool need_hessian_, need_gradient_;
|
---|
92 | bool need_basis_hessian_, need_basis_gradient_;
|
---|
93 |
|
---|
94 | bool using_shared_data_;
|
---|
95 |
|
---|
96 | double accuracy_;
|
---|
97 | virtual void init_common_data(bool initialize_density_matrices);
|
---|
98 | // this must be called after common data is initialized,
|
---|
99 | // either with init_common_data or by copying
|
---|
100 | virtual void init_scratch_data();
|
---|
101 | void compute_basis_values(const SCVector3&r);
|
---|
102 | void compute_spin_density(const double *dmat,
|
---|
103 | double *rho, double *grad, double *hess);
|
---|
104 |
|
---|
105 | virtual void compute();
|
---|
106 | public:
|
---|
107 |
|
---|
108 | /** This gives the elements of gradient arrays. */
|
---|
109 | enum {X=0, Y=1, Z=2};
|
---|
110 | /** This gives the elements of hessian arrays. */
|
---|
111 | enum {XX=0, YX=1, YY=2, ZX=3, ZY=4, ZZ=5};
|
---|
112 |
|
---|
113 | BatchElectronDensity(const Ref<KeyVal>&);
|
---|
114 | BatchElectronDensity(const Ref<Wavefunction>&, double accuracy=DBL_EPSILON);
|
---|
115 | /** This will construct copies of this. If reference_parent_data is
|
---|
116 | true, then data that do not change, such as the density matrices
|
---|
117 | and shell extent, are referenced rather than copied. In this case,
|
---|
118 | the original object that allocated this items must be valid while
|
---|
119 | copied objects are used to compute densities. Also d must have
|
---|
120 | already been intialized and the resulting copy is already initialized
|
---|
121 | (and cannot be reinitialized).
|
---|
122 |
|
---|
123 | If reference_parent_data is false, then init must be called on this
|
---|
124 | object before it is used. */
|
---|
125 | BatchElectronDensity(const Ref<BatchElectronDensity>& d,
|
---|
126 | bool reference_parent_data=false);
|
---|
127 | ~BatchElectronDensity();
|
---|
128 | /** Returns the bounding box. */
|
---|
129 | virtual void boundingbox(double valuemin,
|
---|
130 | double valuemax,
|
---|
131 | SCVector3& p1, SCVector3& p2);
|
---|
132 |
|
---|
133 | /** This will cause all stratch storage to be released. */
|
---|
134 | void clear();
|
---|
135 |
|
---|
136 | /** This is a alternate to the Volume interface that avoids some of the
|
---|
137 | overhead of that interface. */
|
---|
138 | void compute_density(const SCVector3 &r,
|
---|
139 | double *alpha_density,
|
---|
140 | double *alpha_density_grad,
|
---|
141 | double *alpha_density_hessian,
|
---|
142 | double *beta_density,
|
---|
143 | double *beta_density_grad,
|
---|
144 | double *beta_density_hessian);
|
---|
145 |
|
---|
146 | /** This is called to finish initialization of the object. It must not
|
---|
147 | be called with objects that created in a way that they share parent
|
---|
148 | data, those objects are initialized when they are constructed. This
|
---|
149 | member is usually called automatically, however, if it will be used
|
---|
150 | to initial other objects that share parent data, then it must be
|
---|
151 | initialized first and this return is the way to do that. If
|
---|
152 | initialize_density_matrices is false, then the density matrices
|
---|
153 | will be allocated, but not filled in. They must be later filled in
|
---|
154 | with set_densities. */
|
---|
155 | virtual void init(bool initialize_density_matrices = true);
|
---|
156 |
|
---|
157 | /** This will fill in the internel copies of the density matrices with
|
---|
158 | new values. aden is the alpha density matrix and bden is the beta
|
---|
159 | density matrix. bden is ignored if the wavefunction is not spin
|
---|
160 | polarized. */
|
---|
161 | virtual void set_densities(const RefSymmSCMatrix &aden,
|
---|
162 | const RefSymmSCMatrix &bden);
|
---|
163 |
|
---|
164 | /** Turn linear scaling algorithm on/off. The effect of this will be
|
---|
165 | delayed until the next time init() is called. */
|
---|
166 | void set_linear_scaling(bool b) { linear_scaling_ = b; }
|
---|
167 |
|
---|
168 | /** Sets the accuracy. */
|
---|
169 | void set_accuracy(double a) { accuracy_ = a; }
|
---|
170 |
|
---|
171 | /** Turn use of density matrix bounds on/off. */
|
---|
172 | void set_use_dmat_bound(bool b) { use_dmat_bound_ = b; }
|
---|
173 |
|
---|
174 | /** @name DFT Support Members.
|
---|
175 | These return some of the internal data, some of which is
|
---|
176 | only value after a density has been computed. This data
|
---|
177 | is needed by the density functional theory code. */
|
---|
178 | //@{
|
---|
179 | /** Return the alpha density matrix. */
|
---|
180 | double *alpha_density_matrix() { return alpha_dmat_; }
|
---|
181 | /** Return the beta density matrix. */
|
---|
182 | double *beta_density_matrix()
|
---|
183 | { return (spin_polarized_?beta_dmat_:alpha_dmat_); }
|
---|
184 | int ncontrib() { return ncontrib_; }
|
---|
185 | int *contrib() { return contrib_; }
|
---|
186 | int ncontrib_bf() { return ncontrib_bf_; }
|
---|
187 | int *contrib_bf() { return contrib_bf_; }
|
---|
188 | double *bs_values() { return bs_values_; }
|
---|
189 | double *bsg_values() { return bsg_values_; }
|
---|
190 | double *bsh_values() { return bsh_values_; }
|
---|
191 | /** To ensure that that the basis functions gradients are computed,
|
---|
192 | use this. */
|
---|
193 | void set_need_basis_gradient(bool b) { need_basis_gradient_ = b; }
|
---|
194 | void set_need_basis_hessian(bool b) { need_basis_hessian_ = b; }
|
---|
195 | //@}
|
---|
196 | };
|
---|
197 |
|
---|
198 | class DensityColorizer: public MoleculeColorizer {
|
---|
199 | protected:
|
---|
200 | Ref<Wavefunction> wfn_;
|
---|
201 | double scale_;
|
---|
202 | double reference_;
|
---|
203 | int have_scale_;
|
---|
204 | int have_reference_;
|
---|
205 | public:
|
---|
206 | DensityColorizer(const Ref<KeyVal>&);
|
---|
207 | ~DensityColorizer();
|
---|
208 |
|
---|
209 | void colorize(const Ref<RenderedPolygons> &);
|
---|
210 | };
|
---|
211 |
|
---|
212 | class GradDensityColorizer: public MoleculeColorizer {
|
---|
213 | protected:
|
---|
214 | Ref<Wavefunction> wfn_;
|
---|
215 | double scale_;
|
---|
216 | double reference_;
|
---|
217 | int have_scale_;
|
---|
218 | int have_reference_;
|
---|
219 | public:
|
---|
220 | GradDensityColorizer(const Ref<KeyVal>&);
|
---|
221 | ~GradDensityColorizer();
|
---|
222 |
|
---|
223 | void colorize(const Ref<RenderedPolygons> &);
|
---|
224 | };
|
---|
225 |
|
---|
226 | }
|
---|
227 |
|
---|
228 | #endif
|
---|
229 |
|
---|
230 | // Local Variables:
|
---|
231 | // mode: c++
|
---|
232 | // c-file-style: "CLJ"
|
---|
233 | // End:
|
---|