⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clscf.cc

📁 大型并行量子化学软件;支持密度泛函(DFT)。可以进行各种量子化学计算。支持CHARMM并行计算。非常具有应用价值。
💻 CC
📖 第 1 页 / 共 2 页
字号:
//// clscf.cc --- implementation of the closed shell SCF class//// Copyright (C) 1996 Limit Point Systems, Inc.//// Author: Edward Seidl <seidl@janed.com>// Maintainer: LPS//// This file is part of the SC Toolkit.//// The SC Toolkit is free software; you can redistribute it and/or modify// it under the terms of the GNU Library General Public License as published by// the Free Software Foundation; either version 2, or (at your option)// any later version.//// The SC Toolkit is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU Library General Public License for more details.//// You should have received a copy of the GNU Library General Public License// along with the SC Toolkit; see the file COPYING.LIB.  If not, write to// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.//// The U.S. Government is granted a limited license as per AL 91-7.//#ifdef __GNUC__#pragma implementation#endif#include <math.h>#include <util/misc/timer.h>#include <util/misc/formio.h>#include <util/state/stateio.h>#include <math/scmat/block.h>#include <math/scmat/blocked.h>#include <math/scmat/blkiter.h>#include <math/scmat/local.h>#include <math/optimize/scextrapmat.h>#include <chemistry/qc/basis/petite.h>#include <chemistry/qc/scf/scflocal.h>#include <chemistry/qc/scf/scfops.h>#include <chemistry/qc/scf/clscf.h>#include <chemistry/qc/scf/ltbgrad.h>#include <chemistry/qc/scf/clhftmpl.h>using namespace std;using namespace sc;namespace sc {///////////////////////////////////////////////////////////////////////////// CLSCFstatic ClassDesc CLSCF_cd(  typeid(CLSCF),"CLSCF",2,"public SCF",  0, 0, 0);CLSCF::CLSCF(StateIn& s) :  SavableState(s),  SCF(s),  cl_fock_(this){  cl_fock_.result_noupdate() =    basis_matrixkit()->symmmatrix(so_dimension());  cl_fock_.restore_state(s);  cl_fock_.result_noupdate().restore(s);    s.get(user_occupations_);  s.get(tndocc_);  s.get(nirrep_);  s.get(ndocc_);  if (s.version(::class_desc<CLSCF>()) >= 2) {    s.get(initial_ndocc_);    most_recent_pg_ << SavableState::restore_state(s);  } else {    initial_ndocc_ = new int[nirrep_];    memcpy(initial_ndocc_, ndocc_, sizeof(int)*nirrep_);  }  // now take care of memory stuff  init_mem(2);}CLSCF::CLSCF(const Ref<KeyVal>& keyval) :  SCF(keyval),  cl_fock_(this){  int i;  int me = scf_grp_->me();    cl_fock_.compute()=0;  cl_fock_.computed()=0;    // calculate the total nuclear charge  double Znuc=molecule()->nuclear_charge();  // check to see if this is to be a charged molecule  double charge = keyval->intvalue("total_charge");  int nelectron = (int)((Znuc-charge+1.0e-4));    // now see if ndocc was specified  if (keyval->exists("ndocc")) {    tndocc_ = keyval->intvalue("ndocc");  } else {    tndocc_ = nelectron/2;    if (nelectron%2 && me==0) {      ExEnv::err0() << endl           << indent << "CLSCF::init: Warning, there's a leftover electron.\n"           << incindent << indent << "total_charge = " << charge << endl           << indent << "total nuclear charge = " << Znuc << endl           << indent << "ndocc_ = " << tndocc_ << endl << decindent;    }  }  ExEnv::out0() << endl << indent       << "CLSCF::init: total charge = " << Znuc-2*tndocc_ << endl << endl;  nirrep_ = molecule()->point_group()->char_table().ncomp();  ndocc_ = read_occ(keyval, "docc", nirrep_);  if (ndocc_) {    user_occupations_=1;    initial_ndocc_ = new int[nirrep_];    memcpy(initial_ndocc_, ndocc_, sizeof(int)*nirrep_);  } else {    initial_ndocc_=0;    ndocc_=0;    user_occupations_=0;    set_occupations(0);  }  ExEnv::out0() << indent << "docc = [";  for (i=0; i < nirrep_; i++)    ExEnv::out0() << " " << ndocc_[i];  ExEnv::out0() << " ]\n";  ExEnv::out0() << indent << "nbasis = " << basis()->nbasis() << endl;  // check to see if this was done in SCF(keyval)  if (!keyval->exists("maxiter"))    maxiter_ = 40;  // now take care of memory stuff  init_mem(2);}CLSCF::~CLSCF(){  if (ndocc_) {    delete[] ndocc_;    ndocc_=0;  }  delete[] initial_ndocc_;}voidCLSCF::save_data_state(StateOut& s){  SCF::save_data_state(s);  cl_fock_.save_data_state(s);  cl_fock_.result_noupdate().save(s);    s.put(user_occupations_);  s.put(tndocc_);  s.put(nirrep_);  s.put(ndocc_,nirrep_);  s.put(initial_ndocc_,nirrep_);  SavableState::save_state(most_recent_pg_.pointer(),s);}doubleCLSCF::occupation(int ir, int i){  if (i < ndocc_[ir]) return 2.0;  return 0.0;}intCLSCF::n_fock_matrices() const{  return 1;}RefSymmSCMatrixCLSCF::fock(int n){  if (n > 0) {    ExEnv::err0() << indent         << "CLSCF::fock: there is only one fock matrix, "         << scprintf("but fock(%d) was requested\n",n);    abort();  }  return cl_fock_.result();}intCLSCF::spin_polarized(){  return 0;}voidCLSCF::print(ostream&o) const{  SCF::print(o);  o << indent << "CLSCF Parameters:\n" << incindent    << indent << "charge = " << molecule()->nuclear_charge()-2*tndocc_ << endl    << indent << "ndocc = " << tndocc_ << endl    << indent << "docc = [";  for (int i=0; i < nirrep_; i++)    o << " " << ndocc_[i];  o << " ]" << endl << decindent << endl;}//////////////////////////////////////////////////////////////////////////////voidCLSCF::set_occupations(const RefDiagSCMatrix& ev){  if (user_occupations_ || (initial_ndocc_ && ev.null())) {    if (form_occupations(ndocc_, initial_ndocc_)) {      most_recent_pg_ = new PointGroup(molecule()->point_group());      return;    }    ExEnv::out0() << indent         << "CLSCF: WARNING: reforming occupation vector from scratch" << endl;  }    if (nirrep_==1) {    delete[] ndocc_;    ndocc_=new int[1];    ndocc_[0]=tndocc_;    if (!initial_ndocc_) {      initial_ndocc_=new int[1];      initial_ndocc_[0]=tndocc_;    }    return;  }    int i,j;    RefDiagSCMatrix evals;    if (ev.null()) {    initial_vector(0);    evals = eigenvalues_.result_noupdate();  }  else    evals = ev;  // first convert evals to something we can deal with easily  BlockedDiagSCMatrix *evalsb = require_dynamic_cast<BlockedDiagSCMatrix*>(evals,                                                 "CLSCF::set_occupations");    double **vals = new double*[nirrep_];  for (i=0; i < nirrep_; i++) {    int nf=oso_dimension()->blocks()->size(i);    if (nf) {      vals[i] = new double[nf];      evalsb->block(i)->convert(vals[i]);    } else {      vals[i] = 0;    }  }  // now loop to find the tndocc_ lowest eigenvalues and populate those  // MO's  int *newocc = new int[nirrep_];  memset(newocc,0,sizeof(int)*nirrep_);  for (i=0; i < tndocc_; i++) {    // find lowest eigenvalue    int lir=0,ln=0;    double lowest=999999999;    for (int ir=0; ir < nirrep_; ir++) {      int nf=oso_dimension()->blocks()->size(ir);      if (!nf)        continue;      for (j=0; j < nf; j++) {        if (vals[ir][j] < lowest) {          lowest=vals[ir][j];          lir=ir;          ln=j;        }      }    }    vals[lir][ln]=999999999;    newocc[lir]++;  }  // get rid of vals  for (i=0; i < nirrep_; i++)    if (vals[i])      delete[] vals[i];  delete[] vals;  if (!ndocc_) {    ndocc_=newocc;  } else if (most_recent_pg_.nonnull()             && most_recent_pg_->equiv(molecule()->point_group())) {    // test to see if newocc is different from ndocc_    for (i=0; i < nirrep_; i++) {      if (ndocc_[i] != newocc[i]) {        ExEnv::err0() << indent << "CLSCF::set_occupations:  WARNING!!!!\n"             << incindent << indent             << scprintf("occupations for irrep %d have changed\n",i+1)             << indent             << scprintf("ndocc was %d, changed to %d", ndocc_[i],newocc[i])             << endl << decindent;      }    }    memcpy(ndocc_,newocc,sizeof(int)*nirrep_);    delete[] newocc;  }  if (!initial_ndocc_      || initial_pg_->equiv(molecule()->point_group())) {    delete[] initial_ndocc_;    initial_ndocc_ = new int[nirrep_];    memcpy(initial_ndocc_,ndocc_,sizeof(int)*nirrep_);  }  most_recent_pg_ = new PointGroup(molecule()->point_group());}voidCLSCF::symmetry_changed(){  SCF::symmetry_changed();  cl_fock_.result_noupdate()=0;  nirrep_ = molecule()->point_group()->char_table().ncomp();  set_occupations(0);}////////////////////////////////////////////////////////////////////////////////// scf things//

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -