coor.cc

来自「大型并行量子化学软件;支持密度泛函(DFT)。可以进行各种量子化学计算。支持CH」· CC 代码 · 共 1,155 行 · 第 1/2 页

CC
1,155
字号
//// coor.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 <set>#include <math.h>#include <util/misc/formio.h>#include <util/state/stateio.h>#include <math/scmat/matrix.h>#include <chemistry/molecule/molecule.h>#include <chemistry/molecule/coor.h>#include <chemistry/molecule/simple.h>#include <chemistry/molecule/localdef.h>#include <util/container/bitarray.h>using namespace std;using namespace sc;///////////////////////////////////////////////////////////////////////////// members of IntCoordouble IntCoor::bohr_conv = 0.52917706;double IntCoor::radian_conv = 180.0/3.14159265358979323846;static ClassDesc IntCoor_cd(  typeid(IntCoor),"IntCoor",1,"public SavableState",  0, 0, 0);IntCoor::IntCoor(const char *re):  label_(0), value_(0.0){  if (!re) re = "noname";  label_=new char[strlen(re)+1]; strcpy(label_,re);}IntCoor::IntCoor(const IntCoor& c):  label_(0){  value_ = c.value_;  if (c.label_) label_ = strcpy(new char[strlen(c.label_)+1],c.label_);}IntCoor::IntCoor(const Ref<KeyVal>&keyval){  label_ = keyval->pcharvalue("label");  value_ = keyval->doublevalue("value");  char* unit = keyval->pcharvalue("unit");  if (unit) {      if (!strcmp(unit, "bohr")) {        }      else if (!strcmp(unit, "angstrom")) {          value_ /= bohr_conv;        }      else if (!strcmp(unit, "radian")) {        }      else if (!strcmp(unit, "degree")) {          value_ *= M_PI/180.0;        }      else {          ExEnv::err0() << indent               << "IntCoor::IntCoor(KeyVal): unknown unit = \""               << unit << "\"\n";          abort();        }      delete[] unit;    }}IntCoor::IntCoor(StateIn& si):  SavableState(si){  si.get(value_);  si.getstring(label_);}IntCoor::~IntCoor(){  if (label_) delete[] label_;}voidIntCoor::save_data_state(StateOut& so){  so.put(value_);  so.putstring(label_);}const char*IntCoor::label() const{  return label_;}doubleIntCoor::value() const{  return value_;}voidIntCoor::set_value(double v){  value_ = v;}voidIntCoor::print(ostream &o) const{  print_details(0,o);}voidIntCoor::print_details(const Ref<Molecule> &mol, ostream& os) const{  os.setf(ios::fixed,ios::floatfield);  os.precision(10);  os.setf(ios::left,ios::adjustfield);  os.width(10);  os << indent     << scprintf("%-5s \"%10s\" %15.10f\n",ctype(),label(),preferred_value());}doubleIntCoor::preferred_value() const{  return value_;}///////////////////////////////////////////////////////////////////////////// members of SetIntCoorstatic ClassDesc SetIntCoor_cd(  typeid(SetIntCoor),"SetIntCoor",1,"public SavableState",  create<SetIntCoor>, create<SetIntCoor>, create<SetIntCoor>);SetIntCoor::SetIntCoor(){}SetIntCoor::SetIntCoor(const Ref<KeyVal>& keyval){  int n = keyval->count();  Ref<IntCoorGen> gen; gen << keyval->describedclassvalue("generator");  if (gen.null() && !n) {      ExEnv::err0() << indent << "SetIntCoor::SetIntCoor: bad input\n";      abort();    }  if (gen.nonnull()) {      // Make sure that gen doesn't delete me before my reference      // count gets incremented.      this->reference();      gen->generate(this);      // Now it is safe to decrement my reference count back down to zero.      this->dereference();    }  for (int i=0; i<n; i++) {      Ref<IntCoor> coori; coori << keyval->describedclassvalue(i);      coor_.push_back(coori);    }}SetIntCoor::SetIntCoor(StateIn& s):  SavableState(s){  int n;  s.get(n);  Ref<IntCoor> tmp;  for (int i=0; i<n; i++) {      tmp << SavableState::restore_state(s);      coor_.push_back(tmp);    }}SetIntCoor::~SetIntCoor(){}voidSetIntCoor::save_data_state(StateOut& s){  int n = coor_.size();  s.put(n);  for (int i=0; i<n; i++) {      SavableState::save_state(coor_[i].pointer(),s);    }}voidSetIntCoor::add(const Ref<IntCoor>& coor){  coor_.push_back(coor);}voidSetIntCoor::add(const Ref<SetIntCoor>& coor){  for (int i=0; i<coor->n(); i++) {      coor_.push_back(coor->coor(i));    }}voidSetIntCoor::pop(){  coor_.pop_back();}intSetIntCoor::n() const{  return coor_.size();}Ref<IntCoor>SetIntCoor::coor(int i) const{  return coor_[i];}// compute the bmatrix by finite displacementsvoidSetIntCoor::fd_bmat(const Ref<Molecule>& mol,RefSCMatrix& fd_bmatrix){  Ref<SCMatrixKit> kit = fd_bmatrix.kit();  fd_bmatrix.assign(0.0);    int i;  Molecule& m = * mol.pointer();  const double cart_disp = 0.01;  RefSCDimension dn3(fd_bmatrix.coldim());  RefSCDimension dnc(fd_bmatrix.rowdim());  int n3 = dn3.n();  int nc = dnc.n();  RefSCVector internal(dnc,kit);  RefSCVector internal_p(dnc,kit);  RefSCVector internal_m(dnc,kit);  // the internal coordinates  update_values(mol);  for (i=0; i<nc; i++) {      internal(i) = coor_[i]->value();    }  // the finite displacement bmat  for (i=0; i<n3; i++) {      // the plus displacement      m.r(i/3,i%3) += cart_disp;      update_values(mol);      int j;      for (j=0; j<nc; j++) {          internal_p(j) = coor_[j]->value();        }      // the minus displacement      m.r(i/3,i%3) -= 2.0*cart_disp;      update_values(mol);      for (j=0; j<nc; j++) {          internal_m(j) = coor_[j]->value();        }      // reset the cartesian coordinate to its original value      m.r(i/3,i%3) += cart_disp;      // construct the entries in the finite displacement bmat      for (j=0; j<nc; j++) {          fd_bmatrix(j,i) = (internal_p(j)-internal_m(j))/(2.0*cart_disp);        }    }}voidSetIntCoor::bmat(const Ref<Molecule>& mol, RefSCMatrix& bmat){  bmat.assign(0.0);  int i, ncoor = n();  RefSCVector bmatrow(bmat.coldim(),bmat.kit());  // send the rows of the b matrix to each of the coordinates  for (i=0; i<ncoor; i++) {      bmatrow.assign(0.0);      coor_[i]->bmat(mol,bmatrow);      bmat.assign_row(bmatrow,i);    }}voidSetIntCoor::guess_hessian(Ref<Molecule>& mol,RefSymmSCMatrix& hessian){  int ncoor = hessian.n();  hessian.assign(0.0);  for (int i=0; i<ncoor; i++) {      hessian(i,i) = coor_[i]->force_constant(mol);    }}voidSetIntCoor::print_details(const Ref<Molecule> &mol, ostream& os) const{  int i;  for(i=0; i<coor_.size(); i++) {      coor_[i]->print_details(mol,os);    }}voidSetIntCoor::update_values(const Ref<Molecule>&mol){  for (int i=0; i<coor_.size(); i++) {      coor_[i]->update_value(mol);    }}voidSetIntCoor::values_to_vector(const RefSCVector&v){  for (int i=0; i<coor_.size(); i++) {      v(i) = coor_[i]->value();    }}  voidSetIntCoor::clear(){  coor_.clear();}///////////////////////////////////////////////////////////////////////////// members of SumIntCoorstatic ClassDesc SumIntCoor_cd(  typeid(SumIntCoor),"SumIntCoor",1,"public IntCoor",  0, create<SumIntCoor>, create<SumIntCoor>);SumIntCoor::SumIntCoor(const char* label):  IntCoor(label){}SumIntCoor::SumIntCoor(const Ref<KeyVal>&keyval):  IntCoor(keyval){  static const char* coor = "coor";  static const char* coef = "coef";  int n = keyval->count(coor);  int ncoef = keyval->count(coef);  if (n != ncoef || !n) {      ExEnv::err0() << indent << "SumIntCoor::SumIntCoor: bad input\n";      abort();    }  for (int i=0; i<n; i++) {      double coe = keyval->doublevalue(coef,i);      Ref<IntCoor> coo; coo << keyval->describedclassvalue(coor,i);      add(coo,coe);    }}SumIntCoor::SumIntCoor(StateIn&s):  IntCoor(s){  int n;  s.get(n);  coef_.resize(n);  coor_.resize(n);  for (int i=0; i<n; i++) {      s.get(coef_[i]);      coor_[i] << SavableState::restore_state(s);    }}SumIntCoor::~SumIntCoor(){}voidSumIntCoor::save_data_state(StateOut&s){  int n = coef_.size();  IntCoor::save_data_state(s);  s.put(int(coef_.size()));  for (int i=0; i<n; i++) {      s.put(coef_[i]);      SavableState::save_state(coor_[i].pointer(),s);    }}intSumIntCoor::n(){  return coef_.size();}voidSumIntCoor::add(Ref<IntCoor>&coor,double coef){  // if a sum is added to a sum, unfold the nested sum  SumIntCoor* scoor = dynamic_cast<SumIntCoor*>(coor.pointer());  if (scoor) {      int l = scoor->coor_.size();      for (int i=0; i<l; i++) {          add(scoor->coor_[i],coef * scoor->coef_[i]);        }    }  else {      int l = coef_.size();      for (int i=0; i<l; i++) {          if (coor_[i]->equivalent(coor)) {              coef_[i] += coef;              return;            }        }      coef_.resize(l+1);      coor_.resize(l+1);      coef_[l] = coef;      coor_[l] = coor;    }}intSumIntCoor::equivalent(Ref<IntCoor>&c){  return 0;}// this normalizes and makes the biggest coordinate positivevoidSumIntCoor::normalize(){  int i;  int n = coef_.size();  double norm = 0.0;  double biggest = 0.0;  for (i=0; i<n; i++) {      norm += coef_[i] * coef_[i];      if (fabs(biggest) < fabs(coef_[i])) biggest = coef_[i];    }  norm = (biggest < 0.0? -1.0:1.0)/sqrt(norm);  for (i=0; i<n; i++) {      coef_[i] = coef_[i]*norm;    }}doubleSumIntCoor::preferred_value() const{  return value_;}const char*SumIntCoor::ctype() const{  return "SUM";}voidSumIntCoor::print_details(const Ref<Molecule> &mol, ostream& os) const{  int initial_indent = SCFormIO::getindent(os);  int i;  os << indent     << scprintf("%-5s %10s %14.10f\n",ctype(),                 (label()?label():""), preferred_value());  for(i=0; i<coor_.size(); i++) {      os << incindent         << indent << scprintf("%14.10f ",coef_[i]);      SCFormIO::setindent(os, SCFormIO::getindent(os) + 15);      os << skipnextindent;      coor_[i]->print_details(mol,os);      SCFormIO::setindent(os, initial_indent);    }}// the SumIntCoor should be normalized before this is called.doubleSumIntCoor::force_constant(Ref<Molecule>&molecule){  double fc = 0.0;    for (int i=0; i<n(); i++) {      fc += coef_[i] * coef_[i] * coor_[i]->force_constant(molecule);    }  return fc;}voidSumIntCoor::update_value(const Ref<Molecule>&molecule){  int i, l = n();  value_ = 0.0;  for (i=0; i<l; i++) {      coor_[i]->update_value(molecule);#if OLD_BMAT      if (dynamic_cast<StreSimpleCo*>(coor_[i]))        value_ += coef_[i] * dynamic_cast<StreSimpleCo*>(coor_[i])->angstrom();      else#endif              value_ += coef_[i] * coor_[i]->value();    }}voidSumIntCoor::bmat(const Ref<Molecule>&molecule,RefSCVector&bmat,double coef){  int i, l = n();    for (i=0; i<l; i++) {      coor_[i]->bmat(molecule,bmat,coef*coef_[i]);    }}///////////////////////////////////////////////////////////////////////////// members of MolecularCoorstatic ClassDesc MolecularCoor_cd(  typeid(MolecularCoor),"MolecularCoor",1,"public SavableState",  0, 0, 0);MolecularCoor::MolecularCoor(Ref<Molecule>&mol):  molecule_(mol){  debug_ = 0;  matrixkit_ = SCMatrixKit::default_matrixkit();  dnatom3_ = new SCDimension(3*molecule_->natom());}MolecularCoor::MolecularCoor(const Ref<KeyVal>&keyval){

⌨️ 快捷键说明

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