source: ThirdParty/mpqc_open/src/lib/chemistry/qc/dft/hsosks.cc@ 47b463

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_ChronosMutex Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction Subpackage_levmar Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since 47b463 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: 14.3 KB
RevLine 
[0b990d]1//
2// hsosks.cc --- implementation of restricted open shell Kohn-Sham SCF
3// derived from clks.cc
4//
5// Copyright (C) 1997 Limit Point Systems, Inc.
6//
7// Author: Edward Seidl <seidl@janed.com>
8// Maintainer: LPS
9//
10// This file is part of the SC Toolkit.
11//
12// The SC Toolkit is free software; you can redistribute it and/or modify
13// it under the terms of the GNU Library General Public License as published by
14// the Free Software Foundation; either version 2, or (at your option)
15// any later version.
16//
17// The SC Toolkit is distributed in the hope that it will be useful,
18// but WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20// GNU Library General Public License for more details.
21//
22// You should have received a copy of the GNU Library General Public License
23// along with the SC Toolkit; see the file COPYING.LIB. If not, write to
24// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25//
26// The U.S. Government is granted a limited license as per AL 91-7.
27//
28
29#ifdef __GNUC__
30#pragma implementation
31#endif
32
33#include <math.h>
34
35#include <util/misc/timer.h>
36#include <util/misc/formio.h>
37#include <util/state/stateio.h>
38
39#include <math/optimize/scextrapmat.h>
40
41#include <chemistry/qc/basis/petite.h>
42
43#include <chemistry/qc/dft/hsosks.h>
44#include <chemistry/qc/scf/lgbuild.h>
45#include <chemistry/qc/scf/ltbgrad.h>
46#include <chemistry/qc/scf/effh.h>
47#include <chemistry/qc/scf/scfops.h>
48
49#include <chemistry/qc/dft/hsoskstmpl.h>
50
51using namespace std;
52using namespace sc;
53
54///////////////////////////////////////////////////////////////////////////
55// HSOSKS
56
57static ClassDesc HSOSKS_cd(
58 typeid(HSOSKS),"HSOSKS",1,"public HSOSSCF",
59 0, create<HSOSKS>, create<HSOSKS>);
60
61HSOSKS::HSOSKS(StateIn& s) :
62 SavableState(s),
63 HSOSSCF(s)
64{
65 exc_=0;
66 integrator_ << SavableState::restore_state(s);
67 functional_ << SavableState::restore_state(s);
68 vxc_a_ = basis_matrixkit()->symmmatrix(so_dimension());
69 vxc_a_.restore(s);
70 vxc_b_ = basis_matrixkit()->symmmatrix(so_dimension());
71 vxc_b_.restore(s);
72}
73
74HSOSKS::HSOSKS(const Ref<KeyVal>& keyval) :
75 HSOSSCF(keyval)
76{
77 exc_=0;
78 integrator_ << keyval->describedclassvalue("integrator");
79 if (integrator_.null()) integrator_ = new RadialAngularIntegrator();
80
81 functional_ << keyval->describedclassvalue("functional");
82 if (functional_.null()) {
83 ExEnv::outn() << "ERROR: " << class_name() << ": no \"functional\" given" << endl;
84 abort();
85 }
86}
87
88HSOSKS::~HSOSKS()
89{
90}
91
92void
93HSOSKS::save_data_state(StateOut& s)
94{
95 HSOSSCF::save_data_state(s);
96 SavableState::save_state(integrator_.pointer(),s);
97 SavableState::save_state(functional_.pointer(),s);
98 vxc_a_.save(s);
99 vxc_b_.save(s);
100}
101
102int
103HSOSKS::value_implemented() const
104{
105 return 1;
106}
107
108int
109HSOSKS::gradient_implemented() const
110{
111 return 1;
112}
113
114void
115HSOSKS::print(ostream&o) const
116{
117 o << indent
118 << "Restricted Open Shell Kohn-Sham (HSOSKS) Parameters:" << endl;
119 o << incindent;
120 HSOSSCF::print(o);
121 o << indent << "Functional:" << endl;
122 o << incindent;
123 functional_->print(o);
124 o << decindent;
125 o << indent << "Integrator:" << endl;
126 o << incindent;
127 integrator_->print(o);
128 o << decindent;
129 o << decindent;
130}
131
132double
133HSOSKS::scf_energy()
134{
135 double ehf = HSOSSCF::scf_energy();
136
137 return ehf+exc_;
138}
139
140RefSymmSCMatrix
141HSOSKS::effective_fock()
142{
143 RefSymmSCMatrix mofock(oso_dimension(), basis_matrixkit());
144 mofock.assign(0.0);
145
146 RefSymmSCMatrix mofocko(oso_dimension(), basis_matrixkit());
147 mofocko.assign(0.0);
148
149 // use eigenvectors if oso_scf_vector_ is null
150 if (oso_scf_vector_.null()) {
151 mofock.accumulate_transform(eigenvectors(), fock(0)+cl_vxc(),
152 SCMatrix::TransposeTransform);
153 mofocko.accumulate_transform(eigenvectors(), fock(1)+op_vxc(),
154 SCMatrix::TransposeTransform);
155 } else {
156 RefSCMatrix so_to_oso_tr = so_to_orthog_so().t();
157 mofock.accumulate_transform(so_to_oso_tr * oso_scf_vector_,
158 fock(0)+cl_vxc(),
159 SCMatrix::TransposeTransform);
160 mofocko.accumulate_transform(so_to_oso_tr * oso_scf_vector_,
161 fock(1)+op_vxc(),
162 SCMatrix::TransposeTransform);
163 }
164
165 Ref<SCElementOp2> op = new GSGeneralEffH(this);
166 mofock.element_op(op, mofocko);
167
168 return mofock;
169}
170
171RefSymmSCMatrix
172HSOSKS::lagrangian()
173{
174 RefSCMatrix so_to_oso_tr = so_to_orthog_so().t();
175
176 RefSymmSCMatrix mofock(oso_dimension(), basis_matrixkit());
177 mofock.assign(0.0);
178 mofock.accumulate_transform(so_to_oso_tr * oso_scf_vector_,
179 cl_fock_.result_noupdate()+cl_vxc(),
180 SCMatrix::TransposeTransform);
181
182 RefSymmSCMatrix mofocko(oso_dimension(), basis_matrixkit());
183 mofocko.assign(0.0);
184 mofocko.accumulate_transform(so_to_oso_tr * oso_scf_vector_,
185 op_fock_.result_noupdate()+op_vxc(),
186 SCMatrix::TransposeTransform);
187
188 mofock.scale(2.0);
189
190 Ref<SCElementOp2> op = new MOLagrangian(this);
191 mofock.element_op(op, mofocko);
192 mofocko=0;
193
194 // transform MO lagrangian to SO basis
195 RefSymmSCMatrix so_lag(so_dimension(), basis_matrixkit());
196 so_lag.assign(0.0);
197 so_lag.accumulate_transform(so_to_oso_tr * oso_scf_vector_, mofock);
198
199 // and then from SO to AO
200 Ref<PetiteList> pl = integral()->petite_list();
201 RefSymmSCMatrix ao_lag = pl->to_AO_basis(so_lag);
202
203 ao_lag.scale(-1.0);
204
205 return ao_lag;
206}
207
208Ref<SCExtrapData>
209HSOSKS::extrap_data()
210{
211 Ref<SCExtrapData> data =
212 new SymmSCMatrix4SCExtrapData(cl_fock_.result_noupdate(),
213 op_fock_.result_noupdate(),
214 vxc_a_, vxc_b_);
215 return data;
216}
217
218//////////////////////////////////////////////////////////////////////////////
219
220void
221HSOSKS::ao_fock(double accuracy)
222{
223 Ref<PetiteList> pl = integral()->petite_list(basis());
224
225 // calculate G. First transform cl_dens_diff_ to the AO basis, then
226 // scale the off-diagonal elements by 2.0
227 RefSymmSCMatrix dd = cl_dens_diff_;
228 cl_dens_diff_ = pl->to_AO_basis(dd);
229 cl_dens_diff_->scale(2.0);
230 cl_dens_diff_->scale_diagonal(0.5);
231
232 RefSymmSCMatrix ddo = op_dens_diff_;
233 op_dens_diff_ = pl->to_AO_basis(ddo);
234 op_dens_diff_->scale(2.0);
235 op_dens_diff_->scale_diagonal(0.5);
236
237 // now try to figure out the matrix specialization we're dealing with
238 // if we're using Local matrices, then there's just one subblock, or
239 // see if we can convert G and P to local matrices
240 if (local_ || local_dens_) {
241 double *gmat, *gmato, *pmat, *pmato;
242
243 // grab the data pointers from the G and P matrices
244 RefSymmSCMatrix gtmp = get_local_data(cl_gmat_, gmat, SCF::Accum);
245 RefSymmSCMatrix ptmp = get_local_data(cl_dens_diff_, pmat, SCF::Read);
246 RefSymmSCMatrix gotmp = get_local_data(op_gmat_, gmato, SCF::Accum);
247 RefSymmSCMatrix potmp = get_local_data(op_dens_diff_, pmato, SCF::Read);
248
249 signed char * pmax = init_pmax(pmat);
250
251// LocalHSOSKSContribution lclc(gmat, pmat, gmato, pmato, functional_->a0());
252// LocalGBuild<LocalHSOSKSContribution>
253// gb(lclc, tbi_, pl, basis(), scf_grp_, pmax, desired_value_accuracy()/100.0);
254// gb.run();
255 int i;
256 int nthread = threadgrp_->nthread();
257 LocalGBuild<LocalHSOSKSContribution> **gblds =
258 new LocalGBuild<LocalHSOSKSContribution>*[nthread];
259 LocalHSOSKSContribution **conts = new LocalHSOSKSContribution*[nthread];
260
261 double **gmats = new double*[nthread];
262 gmats[0] = gmat;
263 double **gmatos = new double*[nthread];
264 gmatos[0] = gmato;
265
266 Ref<GaussianBasisSet> bs = basis();
267 int ntri = i_offset(bs->nbasis());
268
269 double gmat_accuracy = accuracy;
270 if (min_orthog_res() < 1.0) { gmat_accuracy *= min_orthog_res(); }
271
272 for (i=0; i < nthread; i++) {
273 if (i) {
274 gmats[i] = new double[ntri];
275 memset(gmats[i], 0, sizeof(double)*ntri);
276 gmatos[i] = new double[ntri];
277 memset(gmatos[i], 0, sizeof(double)*ntri);
278 }
279 conts[i] = new LocalHSOSKSContribution(gmats[i], pmat, gmatos[i], pmato,
280 functional_->a0());
281 gblds[i] = new LocalGBuild<LocalHSOSKSContribution>(*conts[i], tbis_[i],
282 pl, bs, scf_grp_, pmax, gmat_accuracy, nthread, i
283 );
284
285 threadgrp_->add_thread(i, gblds[i]);
286 }
287
288 tim_enter("start thread");
289 if (threadgrp_->start_threads() < 0) {
290 ExEnv::err0() << indent
291 << "HSOSKS: error starting threads" << endl;
292 abort();
293 }
294 tim_exit("start thread");
295
296 tim_enter("stop thread");
297 if (threadgrp_->wait_threads() < 0) {
298 ExEnv::err0() << indent
299 << "HSOSKS: error waiting for threads" << endl;
300 abort();
301 }
302 tim_exit("stop thread");
303
304 double tnint=0;
305 for (i=0; i < nthread; i++) {
306 tnint += gblds[i]->tnint;
307
308 if (i) {
309 for (int j=0; j < ntri; j++) {
310 gmat[j] += gmats[i][j];
311 gmato[j] += gmatos[i][j];
312 }
313 delete[] gmats[i];
314 delete[] gmatos[i];
315 }
316
317 delete gblds[i];
318 delete conts[i];
319 }
320
321 delete[] gmats;
322 delete[] gmatos;
323 delete[] gblds;
324 delete[] conts;
325
326 delete[] pmax;
327
328 scf_grp_->sum(&tnint, 1, 0, 0);
329 ExEnv::out0() << indent << scprintf("%20.0f integrals\n", tnint);
330
331 // if we're running on multiple processors, then sum the G matrices
332 if (scf_grp_->n() > 1) {
333 scf_grp_->sum(gmat, i_offset(basis()->nbasis()));
334 scf_grp_->sum(gmato, i_offset(basis()->nbasis()));
335 }
336
337 // if we're running on multiple processors, or we don't have local
338 // matrices, then accumulate gtmp back into G
339 if (!local_ || scf_grp_->n() > 1) {
340 cl_gmat_->convert_accumulate(gtmp);
341 op_gmat_->convert_accumulate(gotmp);
342 }
343 }
344
345 // for now quit
346 else {
347 ExEnv::err0() << indent << "Cannot yet use anything but Local matrices\n";
348 abort();
349 }
350
351 RefSymmSCMatrix dens_a = alpha_ao_density();
352 RefSymmSCMatrix dens_b = beta_ao_density();
353 integrator_->set_compute_potential_integrals(1);
354 integrator_->set_accuracy(accuracy);
355 integrator_->integrate(functional_, dens_a, dens_b);
356 exc_ = integrator_->value();
357 vxc_a_ = dens_a.clone();
358 vxc_a_->assign((double*)integrator_->alpha_vmat());
359 vxc_a_ = pl->to_SO_basis(vxc_a_);
360 vxc_b_ = dens_b.clone();
361 vxc_b_->assign((double*)integrator_->beta_vmat());
362 vxc_b_ = pl->to_SO_basis(vxc_b_);
363
364 // get rid of AO delta P
365 cl_dens_diff_ = dd;
366 dd = cl_dens_diff_.clone();
367
368 op_dens_diff_ = ddo;
369 ddo = op_dens_diff_.clone();
370
371 // now symmetrize the skeleton G matrix, placing the result in dd
372 RefSymmSCMatrix skel_gmat = cl_gmat_.copy();
373 skel_gmat.scale(1.0/(double)pl->order());
374 pl->symmetrize(skel_gmat,dd);
375
376 skel_gmat = op_gmat_.copy();
377 skel_gmat.scale(1.0/(double)pl->order());
378 pl->symmetrize(skel_gmat,ddo);
379
380 // F = H+G
381 cl_fock_.result_noupdate().assign(hcore_);
382 cl_fock_.result_noupdate().accumulate(dd);
383
384 // Fo = H+G-Go
385 op_fock_.result_noupdate().assign(cl_fock_.result_noupdate());
386 ddo.scale(-1.0);
387 op_fock_.result_noupdate().accumulate(ddo);
388 ddo=0;
389
390 dd.assign(0.0);
391 accumddh_->accum(dd);
392 cl_fock_.result_noupdate().accumulate(dd);
393 op_fock_.result_noupdate().accumulate(dd);
394 dd=0;
395
396 cl_fock_.computed()=1;
397 op_fock_.computed()=1;
398}
399
400/////////////////////////////////////////////////////////////////////////////
401
402void
403HSOSKS::two_body_energy(double &ec, double &ex)
404{
405 tim_enter("hsosks e2");
406 ec = 0.0;
407 ex = 0.0;
408 if (local_ || local_dens_) {
409 // grab the data pointers from the G and P matrices
410 double *dpmat;
411 double *spmat;
412 tim_enter("local data");
413 RefSymmSCMatrix ddens = beta_ao_density();
414 RefSymmSCMatrix sdens = alpha_ao_density() - ddens;
415 ddens->scale(2.0);
416 ddens->accumulate(sdens);
417 ddens->scale(2.0);
418 ddens->scale_diagonal(0.5);
419 sdens->scale(2.0);
420 sdens->scale_diagonal(0.5);
421 RefSymmSCMatrix dptmp = get_local_data(ddens, dpmat, SCF::Read);
422 RefSymmSCMatrix sptmp = get_local_data(sdens, spmat, SCF::Read);
423 tim_exit("local data");
424
425 // initialize the two electron integral classes
426 Ref<TwoBodyInt> tbi = integral()->electron_repulsion();
427 tbi->set_integral_storage(0);
428
429 signed char * pmax = init_pmax(dpmat);
430
431 LocalHSOSKSEnergyContribution lclc(dpmat, spmat, functional_->a0());
432 Ref<PetiteList> pl = integral()->petite_list();
433 LocalGBuild<LocalHSOSKSEnergyContribution>
434 gb(lclc, tbi, pl, basis(), scf_grp_, pmax,
435 desired_value_accuracy()/100.0);
436 gb.run();
437
438 delete[] pmax;
439
440 ec = lclc.ec;
441 ex = lclc.ex;
442 }
443 else {
444 ExEnv::err0() << indent << "Cannot yet use anything but Local matrices\n";
445 abort();
446 }
447 tim_exit("hsoshf e2");
448}
449
450/////////////////////////////////////////////////////////////////////////////
451
452void
453HSOSKS::two_body_deriv(double * tbgrad)
454{
455 tim_enter("grad");
456
457 int natom3 = 3*molecule()->natom();
458
459 tim_enter("two-body");
460 double *hfgrad = new double[natom3];
461 memset(hfgrad,0,sizeof(double)*natom3);
462 two_body_deriv_hf(hfgrad,functional_->a0());
463 //print_natom_3(hfgrad, "Two-body contribution to DFT gradient");
464 tim_exit("two-body");
465
466 double *dftgrad = new double[natom3];
467 memset(dftgrad,0,sizeof(double)*natom3);
468 RefSymmSCMatrix dens_a = alpha_ao_density();
469 RefSymmSCMatrix dens_b = beta_ao_density();
470 integrator_->init(this);
471 integrator_->set_compute_potential_integrals(0);
472 integrator_->set_accuracy(desired_gradient_accuracy());
473 integrator_->integrate(functional_, dens_a, dens_b, dftgrad);
474 // must unset the wavefunction so we don't have a circular list that
475 // will not be freed with the reference counting memory manager
476 integrator_->done();
477 //print_natom_3(dftgrad, "E-X contribution to DFT gradient");
478
479 scf_grp_->sum(dftgrad, natom3);
480
481 for (int i=0; i<natom3; i++) tbgrad[i] += dftgrad[i] + hfgrad[i];
482 delete[] dftgrad;
483 delete[] hfgrad;
484
485 tim_exit("grad");
486}
487
488RefSymmSCMatrix
489HSOSKS::cl_vxc()
490{
491 RefSymmSCMatrix r = vxc_a_+vxc_b_;
492 r.scale(0.5);
493 return r;
494}
495
496RefSymmSCMatrix
497HSOSKS::op_vxc()
498{
499 RefSymmSCMatrix r = vxc_a_.copy();
500 return r;
501}
502
503/////////////////////////////////////////////////////////////////////////////
504
505void
506HSOSKS::init_vector()
507{
508 integrator_->init(this);
509 HSOSSCF::init_vector();
510}
511
512void
513HSOSKS::done_vector()
514{
515 integrator_->done();
516 HSOSSCF::done_vector();
517}
518
519/////////////////////////////////////////////////////////////////////////////
520
521// Local Variables:
522// mode: c++
523// c-file-style: "ETS"
524// End:
Note: See TracBrowser for help on using the repository browser.