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

📄 diis.cc

📁 大型并行量子化学软件;支持密度泛函(DFT)。可以进行各种量子化学计算。支持CHARMM并行计算。非常具有应用价值。
💻 CC
字号:
//// diis.cc//// Copyright (C) 1996 Limit Point Systems, Inc.//// Author: Curtis Janssen <cljanss@limitpt.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/formio.h>#include <util/state/stateio.h>#include <math/scmat/cmatrix.h>#include <math/optimize/diis.h>using namespace sc;static ClassDesc DIIS_cd(  typeid(DIIS),"DIIS",3,"public SelfConsistentExtrapolation",  0, create<DIIS>, create<DIIS>);voidDIIS::init(){  int dim = ndiis+1;  iter = 0;  btemp = new double[dim];  bmat = new double*[dim];  bold = new double*[ndiis];    if (!btemp || !bmat || !bold) {    ExEnv::err0() << indent         << "DIIS::init: alloc of bmat, bold, and btemp failed\n";    abort();  }    for (int i=0; i < dim; i++) {    bmat[i] = new double[dim];    if (i < dim-1)      bold[i] = new double[ndiis];  }    diism_data = new Ref<SCExtrapData>[ndiis];  diism_error = new Ref<SCExtrapError>[ndiis];}DIIS::DIIS(int strt, int ndi, double dmp, int ngr, int ngrdiis) :  btemp(0), bold(0), bmat(0), diism_data(0), diism_error(0){  start = strt;  ndiis = ndi;  damping_factor = dmp;  ngroup = ngr;  ngroupdiis = ngrdiis;  init();}DIIS::DIIS(StateIn& s) :  SelfConsistentExtrapolation(s),  btemp(0), bold(0), bmat(0), diism_data(0), diism_error(0){  int i;  s.get(start);  s.get(ndiis);  s.get(iter);  if (s.version(::class_desc<DIIS>()) >= 2) {    s.get(ngroup);    s.get(ngroupdiis);  }  s.get(damping_factor);  // alloc storage for arrays  btemp = new double[ndiis+1];  bold = new double*[ndiis];  for (i=0; i < ndiis; i++)    bold[i] = new double[ndiis];  bmat = new double*[ndiis+1];  for (i=0; i <= ndiis; i++)    bmat[i] = new double[ndiis+1];  diism_data = new Ref<SCExtrapData>[ndiis];  diism_error = new Ref<SCExtrapError>[ndiis];  // read arrays  int ndat = iter;  if (iter > ndiis) ndat = ndiis;  if (s.version(::class_desc<DIIS>()) < 3) ndat = ndiis;  s.get_array_double(btemp,ndat+1);  for (i=0; i < ndat; i++)    s.get_array_double(bold[i],ndat);    for (i=0; i <= ndat; i++)    s.get_array_double(bmat[i],ndat+1);    for (i=0; i < ndat; i++) {    diism_data[i] << SavableState::restore_state(s);    diism_error[i] << SavableState::restore_state(s);  }}DIIS::DIIS(const Ref<KeyVal>& keyval):  SelfConsistentExtrapolation(keyval),  btemp(0), bold(0), bmat(0), diism_data(0), diism_error(0){  ndiis = keyval->intvalue("n");  if (keyval->error() != KeyVal::OK) ndiis = 5;  start = keyval->intvalue("start");  if (keyval->error() != KeyVal::OK) start = 1;  ngroup = keyval->intvalue("ngroup");  if (keyval->error() != KeyVal::OK) ngroup = 1;  ngroupdiis = keyval->intvalue("ngroupdiis");  if (keyval->error() != KeyVal::OK) ngroupdiis = 1;  damping_factor = keyval->doublevalue("damping_factor");  if (keyval->error() != KeyVal::OK) damping_factor = 0;    if (ndiis <= 0) {    ExEnv::err0() << indent         << "DIIS::DIIS(const Ref<KeyVal>& keyval): got ndiis = 0\n";    abort();  }  init();}DIIS::~DIIS(){  if (btemp) {    delete[] btemp;    btemp=0;  }  if (bold) {    for (int i=0; i < ndiis; i++) {      if (bold[i])        delete[] bold[i];    }    delete[] bold;    bold=0;  }      if (bmat) {    for (int i=0; i <= ndiis; i++) {      if (bmat[i])        delete[] bmat[i];    }    delete[] bmat;    bmat=0;  }      if (diism_data) {    delete[] diism_data;    diism_data=0;  }  if (diism_error) {    delete[] diism_error;    diism_error=0;  }}voidDIIS::save_data_state(StateOut& s){  int i;  SelfConsistentExtrapolation::save_data_state(s);  s.put(start);  s.put(ndiis);  s.put(iter);  s.put(ngroup);  s.put(ngroupdiis);  s.put(damping_factor);  int ndat = iter;  if (iter > ndiis) ndat = ndiis;  s.put_array_double(btemp, ndat+1);  for (i=0; i < ndat; i++)    s.put_array_double(bold[i], ndat);    for (i=0; i <= ndat; i++)    s.put_array_double(bmat[i], ndat+1);    for (i=0; i < ndat; i++) {    SavableState::save_state(diism_data[i].pointer(),s);    SavableState::save_state(diism_error[i].pointer(),s);  }}voidDIIS::reinitialize(){  iter=0;}voidDIIS::start_extrapolation(){  if (start > iter) start = iter+1;}intDIIS::extrapolate(const Ref<SCExtrapData>& data,                  const Ref<SCExtrapError>& error){  int i, j, k;  int last = iter;  int trial = 0;  int col = iter + 2;  double norm, determ;  double scale;  iter++;  scale = 1.0 + damping_factor;  if (iter > ndiis) {      last = ndiis-1;      col = ndiis+1;      dtemp_data = diism_data[0];      dtemp_error = diism_error[0];      for (i=0; i < last ; i++) {          diism_data[i] = diism_data[i+1];          diism_error[i] = diism_error[i+1];        }      diism_data[last] = dtemp_data;      diism_error[last] = dtemp_error;    }  diism_data[last] = data->copy();  diism_error[last] = error;  set_error(error->error());                 // then set up B matrix, where B(i,j) = <ei|ej>  // move bold(i+1,j+1) to bold(i,j)  if (iter > ndiis) {      for (i=0; i < last ; i++) {          for (j=0; j <= i ; j++) {              bold[i][j]=bold[j][i]=bold[i+1][j+1];            }        }    }  // and set the current rows of bold  for (i=0; i <= last ; i++)      bold[i][last]=bold[last][i] =                       diism_error[i]->scalar_product(diism_error[last]);  bmat[0][0] = 0.0;  btemp[0] = -1.0;  if (bold[0][0] > 1.e-10) {      norm = 1.0/bold[0][0];    }  else {      norm = 1.0;    }  for (i=1; i <= last+1 ; i++) {      bmat[i][0]=bmat[0][i] = -1.0;      btemp[i] = 0.0;      for (j=1; j <= i ; j++) {          bmat[i][j]=bmat[j][i] = bold[i-1][j-1]*norm;          if (i==j) bmat[i][j] *= scale;        }    }  // finally, solve the set of linear equations, obtain the coefficients,  // and form the new fock matrix F= sum(i=1,n) ci*Fi  if (iter-1) {      determ = cmat_solve_lin(bmat,0,btemp,col);      // test for poorly conditioned equations */      while (fabs(determ) < 1.0e-19 && trial < last) {          trial++;          col--;          bmat[0][0] = 0.0;          btemp[0] = -1.0;          if (bold[trial][trial] > 1.e-10) {              norm=1.0/bold[trial][trial];            }          else {              norm = 1.0;            }          for (i=1; i <= last-trial+1 ; i++) {              bmat[i][0]=bmat[0][i] = -1.0;              for (j=1; j <= i ; j++) {                  bmat[i][j]=bmat[j][i]=bold[i+trial-1][j+trial-1]*norm;                  if (i==j) bmat[i][j] *= scale;                }              btemp[i] = 0.0;            }          determ = cmat_solve_lin(bmat,0,btemp,col);        }      if (fabs(determ) < 10.0e-20) {        ExEnv::err0() << indent             << "DIIS::extrapolate:  trial " << trial << " no good\n";        return -1;      }      if (iter >= start && (((iter-start)%ngroup) < ngroupdiis)) {          int kk=1;          data->zero();          for (k=trial; k < last+1 ; k++) {              data->accumulate_scaled(btemp[kk], diism_data[k]);              kk++;            }        }    }  return 0;}/////////////////////////////////////////////////////////////////////////////// Local Variables:// mode: c++// c-file-style: "ETS"// End:

⌨️ 快捷键说明

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