📄 gaussbas.cc
字号:
//// gaussbas.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 <stdio.h>#include <scconfig.h>#ifdef HAVE_SSTREAM# include <sstream>#else# include <strstream.h>#endif#include <util/keyval/keyval.h>#include <util/misc/formio.h>#include <util/misc/newstring.h>#include <util/state/stateio.h>#include <math/scmat/blocked.h>#include <chemistry/molecule/molecule.h>#include <chemistry/qc/basis/gaussshell.h>#include <chemistry/qc/basis/gaussbas.h>#include <chemistry/qc/basis/files.h>#include <chemistry/qc/basis/cartiter.h>#include <chemistry/qc/basis/transform.h>#include <chemistry/qc/basis/integral.h>using namespace std;using namespace sc;static ClassDesc GaussianBasisSet_cd( typeid(GaussianBasisSet),"GaussianBasisSet",3,"public SavableState", 0, create<GaussianBasisSet>, create<GaussianBasisSet>);GaussianBasisSet::GaussianBasisSet(const Ref<KeyVal>&topkeyval){ molecule_ << topkeyval->describedclassvalue("molecule"); if (molecule_.null()) { ExEnv::err0() << indent << "GaussianBasisSet: no \"molecule\"\n"; abort(); } // see if the user requests pure am or cartesian functions int pure; pure = topkeyval->booleanvalue("puream"); if (topkeyval->error() != KeyVal::OK) pure = -1; // construct a keyval that contains the basis library Ref<KeyVal> keyval; if (topkeyval->exists("basisfiles")) { Ref<MessageGrp> grp = MessageGrp::get_default_messagegrp(); Ref<ParsedKeyVal> parsedkv = new ParsedKeyVal(); char *in_char_array; if (grp->me() == 0) {#ifdef HAVE_SSTREAM ostringstream ostrs;#else ostrstream ostrs;#endif // Look at the basisdir and basisfiles variables to find out what // basis set files are to be read in. The files are read on node // 0 only. ParsedKeyVal::cat_files("basis",topkeyval,ostrs);#ifdef HAVE_SSTREAM int n = 1 + strlen(ostrs.str().c_str()); in_char_array = strcpy(new char[n],ostrs.str().c_str());#else ostrs << ends; in_char_array = ostrs.str(); int n = ostrs.pcount();#endif grp->bcast(n); grp->bcast(in_char_array, n); } else { int n; grp->bcast(n); in_char_array = new char[n]; grp->bcast(in_char_array, n); } parsedkv->parse_string(in_char_array); delete[] in_char_array; Ref<KeyVal> libkeyval = parsedkv.pointer(); keyval = new AggregateKeyVal(topkeyval,libkeyval); } else { keyval = topkeyval; } // if there isn't a matrixkit in the input, init2() will assign the // default matrixkit matrixkit_ << keyval->describedclassvalue("matrixkit"); // Bases keeps track of what basis set data bases have already // been read in. It also handles the conversion of basis // names to file names. BasisFileSet bases(keyval); init(molecule_,keyval,bases,1,pure);}GaussianBasisSet::GaussianBasisSet(const GaussianBasisSet& gbs) : molecule_(gbs.molecule_), matrixkit_(gbs.matrixkit_), basisdim_(gbs.basisdim_), ncenter_(gbs.ncenter_), nshell_(gbs.nshell_){ int i,j; name_ = new_string(gbs.name_); center_to_nshell_.resize(ncenter_); for (i=0; i < ncenter_; i++) { center_to_nshell_[i] = gbs.center_to_nshell_[i]; } shell_ = new GaussianShell*[nshell_]; for (i=0; i<nshell_; i++) { const GaussianShell& gsi = gbs(i); int nc=gsi.ncontraction(); int np=gsi.nprimitive(); int *ams = new int[nc]; int *pure = new int[nc]; double *exps = new double[np]; double **coefs = new double*[nc]; for (j=0; j < nc; j++) { ams[j] = gsi.am(j); pure[j] = gsi.is_pure(j); coefs[j] = new double[np]; for (int k=0; k < np; k++) coefs[j][k] = gsi.coefficient_unnorm(j,k); } for (j=0; j < np; j++) exps[j] = gsi.exponent(j); shell_[i] = new GaussianShell(nc, np, exps, ams, pure, coefs, GaussianShell::Unnormalized); } init2();}GaussianBasisSet::GaussianBasisSet(StateIn&s): SavableState(s){ matrixkit_ = SCMatrixKit::default_matrixkit(); if (s.version(::class_desc<GaussianBasisSet>()) < 3) { // read the duplicate length saved in older versions int junk; s.get(junk); } s.get(center_to_nshell_); molecule_ << SavableState::restore_state(s); basisdim_ << SavableState::restore_state(s); ncenter_ = center_to_nshell_.size(); s.getstring(name_); nshell_ = 0; int i; for (i=0; i<ncenter_; i++) { nshell_ += center_to_nshell_[i]; } shell_ = new GaussianShell*[nshell_]; for (i=0; i<nshell_; i++) { shell_[i] = new GaussianShell(s); } init2();}voidGaussianBasisSet::save_data_state(StateOut&s){ s.put(center_to_nshell_); SavableState::save_state(molecule_.pointer(),s); SavableState::save_state(basisdim_.pointer(),s); s.putstring(name_); for (int i=0; i<nshell_; i++) { shell_[i]->save_object_state(s); }}voidGaussianBasisSet::init(Ref<Molecule>&molecule, Ref<KeyVal>&keyval, BasisFileSet& bases, int have_userkeyval, int pur){ int pure, havepure; pure = pur; if (pur == -1) { havepure = 0; } else { havepure = 1; } int skip_ghosts = keyval->booleanvalue("skip_ghosts"); name_ = keyval->pcharvalue("name"); int have_custom, nelement; if (keyval->exists("basis")) { have_custom = 1; nelement = keyval->count("element"); } else { have_custom = 0; nelement = 0; if (!name_) { ExEnv::err0() << indent << "GaussianBasisSet: No name given for basis set\n"; abort(); } } // construct prefixes for each atom: :basis:<atom>:<basisname>:<shell#> // and read in the shell nbasis_ = 0; int ishell = 0; ncenter_ = molecule->natom(); int iatom; for (iatom=0; iatom < ncenter_; iatom++) { if (skip_ghosts && molecule->charge(iatom) == 0.0) continue; int Z = molecule->Z(iatom); // see if there is a specific basisname for this atom char* sbasisname = 0; if (have_custom && !nelement) { sbasisname = keyval->pcharvalue("basis",iatom); } else if (nelement) { int i; for (i=0; i<nelement; i++) { char *tmpelementname = keyval->pcharvalue("element", i); int tmpZ = AtomInfo::string_to_Z(tmpelementname); if (tmpZ == Z) { sbasisname = keyval->pcharvalue("basis", i); break; } delete[] tmpelementname; } } if (!sbasisname) { if (!name_) { ExEnv::err0() << indent << "GaussianBasisSet: " << scprintf("no basis name for atom %d (%s)\n", iatom, AtomInfo::name(Z)); abort(); } sbasisname = strcpy(new char[strlen(name_)+1],name_); } recursively_get_shell(ishell,keyval, AtomInfo::name(Z), sbasisname,bases,havepure,pure,0); delete[] sbasisname; } nshell_ = ishell; shell_ = new GaussianShell*[nshell_]; ishell = 0; center_to_nshell_.resize(ncenter_); for (iatom=0; iatom<ncenter_; iatom++) { if (skip_ghosts && molecule->charge(iatom) == 0.0) { center_to_nshell_[iatom] = 0; continue; } int Z = molecule->Z(iatom); // see if there is a specific basisname for this atom char* sbasisname = 0; if (have_custom && !nelement) { sbasisname = keyval->pcharvalue("basis",iatom); } else if (nelement) { int i; for (i=0; i<nelement; i++) { char *tmpelementname = keyval->pcharvalue("element", i); int tmpZ = AtomInfo::string_to_Z(tmpelementname); if (tmpZ == Z) { sbasisname = keyval->pcharvalue("basis", i); break; } delete[] tmpelementname; } } if (!sbasisname) { if (!name_) { ExEnv::err0() << indent << "GaussianBasisSet: " << scprintf("no basis name for atom %d (%s)\n", iatom, AtomInfo::name(Z)); abort(); } sbasisname = strcpy(new char[strlen(name_)+1],name_); } int ishell_old = ishell; recursively_get_shell(ishell,keyval, AtomInfo::name(Z), sbasisname,bases,havepure,pure,1); center_to_nshell_[iatom] = ishell - ishell_old; delete[] sbasisname; } // delete the name_ if the basis set is customized if (have_custom) { delete[] name_; name_ = 0; } // finish with the initialization steps that don't require any // external information init2(skip_ghosts);}doubleGaussianBasisSet::r(int icenter, int xyz) const{ return molecule_->r(icenter,xyz);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -