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

📄 psiwfn.cc

📁 大型并行量子化学软件;支持密度泛函(DFT)。可以进行各种量子化学计算。支持CHARMM并行计算。非常具有应用价值。
💻 CC
字号:
#ifdef __GNUC__#pragma implementation#endif#include <stdexcept>#include <math.h>#include <util/keyval/keyval.h>#include <util/misc/formio.h>#include <util/state/stateio.h>#include <math/scmat/matrix.h>#include <math/symmetry/pointgrp.h>#include <chemistry/molecule/molecule.h>#include <chemistry/qc/psi/psiwfn.h>using namespace std;namespace sc {//////////////////////////////////////////////////////////////////////////static ClassDesc PsiWavefunction_cd(  typeid(PsiWavefunction),"PsiWavefunction",2,"public Wavefunction",  0, 0, 0);PsiWavefunction::PsiWavefunction(const Ref<KeyVal>&keyval):  Wavefunction(keyval){  exenv_ << keyval->describedclassvalue("psienv");  if (exenv_.null()) {    ExEnv::err0() << "PsiWavefunction::PsiWavefunction: no Psi execution environment object (psienv)" << endl;    abort();  }    nirrep_ = molecule()->point_group()->char_table().order();  docc_ = read_occ(keyval,"docc",nirrep_);  socc_ = read_occ(keyval,"socc",nirrep_);  frozen_docc_ = read_occ(keyval,"frozen_docc",nirrep_);  frozen_uocc_ = read_occ(keyval,"frozen_uocc",nirrep_);  int bytes = keyval->intvalue("memory");  if (bytes <= 2000000)    bytes = 2000000;  int bytes_str_len = (int)ceil(log10((long double)bytes));  memory_ = new char[bytes_str_len+5];  sprintf(memory_,"(%ld B)",bytes);}PsiWavefunction::~PsiWavefunction(){}PsiWavefunction::PsiWavefunction(StateIn&s):  SavableState(s),  Wavefunction(s){  throw std::runtime_error("PsiWavefunction::PsiWavefunction(StateIn&) -- cannot restore state of Psi wave functions");}voidPsiWavefunction::save_data_state(StateOut&s){  throw std::runtime_error("PsiWavefunction::save_data_state -- cannot save state of Psi wave functions, set savestate = no in your input file");}voidPsiWavefunction::print(ostream&o) const{  Wavefunction::print(o);  exenv_->print(o);}voidPsiWavefunction::compute(){    if (gradient_needed() && !gradient_implemented()) {    ExEnv::out0() << scprintf("Gradient is not implemented for this Psi wavefunction") << endl;    abort();  }  double energy_acc = desired_value_accuracy();  double grad_acc = desired_gradient_accuracy();  if (energy_acc > 1.0e-6) energy_acc = 1.0e-6;  if (grad_acc > 1.0e-7) grad_acc = 1.0e-7;  if (gradient_needed() && energy_acc > grad_acc/10.0)      energy_acc = grad_acc/10.0;  write_input((int)-log10(energy_acc));  exenv_->run_psi();  // read output  if (gradient_needed()) {    Ref<PsiFile11> file11 = exenv_->get_psi_file11();    file11->open();    set_energy(file11->get_energy(0));    set_actual_value_accuracy(energy_acc);    int natom_mpqc = molecule()->natom();    int natom = file11->get_natom(0);    if (natom != natom_mpqc) {      ExEnv::out0() << scprintf("Number of atoms in MPQC and Psi3 do not match") << endl;      abort();    }    RefSCVector gradientvec = basis()->matrixkit()->vector(moldim());    for(int atom=0; atom<natom; atom++) {      gradientvec[3*atom] = file11->get_grad(0,atom,0);      gradientvec[3*atom+1] = file11->get_grad(0,atom,1);      gradientvec[3*atom+2] = file11->get_grad(0,atom,2);    }    set_gradient(gradientvec);    file11->close();    file11->remove();  }  else {      double energy = 0.0;;      set_energy(energy);      set_actual_value_accuracy(energy_acc);  }}RefSymmSCMatrixPsiWavefunction::density(){  abort();  return 0;}intPsiWavefunction::nelectron(){  abort();  return 0;}voidPsiWavefunction::write_basic_input(int conv){  const char *dertype = gradient_needed() ? "first" : "none";  Ref<PsiInput> psiinput = get_psi_input();  psiinput->write_defaults(exenv_,dertype);  psiinput->write_keyword("psi:memory",memory_);  psiinput->begin_section("input");  psiinput->write_keyword("no_reorient","true");  psiinput->write_keyword("keep_ref_frame","true");  psiinput->write_basis(basis());  if (basis()->max_nfunction_in_shell() != basis()->max_ncartesian_in_shell())    psiinput->write_keyword("puream","true");  psiinput->write_geom(molecule());  psiinput->end_section();  psiinput->write_basis_sets(basis());}// Shamelessly borrowed from class SCFint *PsiWavefunction::read_occ(const Ref<KeyVal> &keyval, const char *name, int nirrep){  int *occ = 0;  if (keyval->exists(name)) {    if (keyval->count(name) != nirrep) {      ExEnv::err0() << indent                   << "ERROR: PsiWavefunction: have " << nirrep << " irreps but "                   << name << " vector is length " << keyval->count(name)                   << endl;      abort();    }    occ = new int[nirrep];    for (int i=0; i<nirrep; i++) {      occ[i] = keyval->intvalue(name,i);    }  }  return occ;}//////////////////////////////////////////////////////////////////////////static ClassDesc PsiSCF_cd(  typeid(PsiSCF),"PsiSCF",1,"public PsiWavefunction",  0, 0, 0);PsiSCF::PsiSCF(const Ref<KeyVal>&keyval):  PsiWavefunction(keyval){  if (!docc_ || !socc_) {    if (keyval->exists("total_charge") && keyval->exists("multiplicity")) {      charge_ = keyval->intvalue("total_charge");      multp_ = keyval->intvalue("multiplicity");      if (multp_ < 1) {	ExEnv::err0() << indent		      << "ERROR: PsiSCF: valid multiplicity has to be >= 1" << endl;	abort();      }    }    else {      ExEnv::err0() << indent		    << "ERROR: PsiSCF: multiplicity and total_charge need "		    << "to be specified when docc (socc) are missing" << endl;      abort();    }  }}PsiSCF::~PsiSCF(){}PsiSCF::PsiSCF(StateIn&s):  PsiWavefunction(s){}voidPsiSCF::save_data_state(StateOut&s){  PsiWavefunction::save_data_state(s);}//////////////////////////////////////////////////////////////////////////static ClassDesc PsiCLHF_cd(  typeid(PsiCLHF),"PsiCLHF",1,"public PsiSCF",  0, create<PsiCLHF>, create<PsiCLHF>);PsiCLHF::PsiCLHF(const Ref<KeyVal>&keyval):  PsiSCF(keyval){  if (!docc_ && multp_ != 1) {    ExEnv::err0() << indent		  << "ERROR: PsiCLHF: multiplicity should be 1 for CLHF wave function" << endl;    abort();  }}PsiCLHF::~PsiCLHF(){}PsiCLHF::PsiCLHF(StateIn&s):  PsiSCF(s){}voidPsiCLHF::write_basic_input(int convergence){  Ref<PsiInput> input = get_psi_input();  input->write_keyword("psi:reference","rhf");  if (docc_)    input->write_keyword_array("psi:docc",nirrep_,docc_);  else {    input->write_keyword("psi:multp",multp_);    input->write_keyword("psi:charge",charge_);  }}voidPsiCLHF::write_input(int convergence){  Ref<PsiInput> input = get_psi_input();  input->open();  PsiWavefunction::write_basic_input(convergence);  write_basic_input(convergence);  input->write_keyword("psi:wfn","scf");  input->close();}//////////////////////////////////////////////////////////////////////////static ClassDesc PsiHSOSHF_cd(  typeid(PsiHSOSHF),"PsiHSOSHF",1,"public PsiSCF",  0, create<PsiHSOSHF>, create<PsiHSOSHF>);PsiHSOSHF::PsiHSOSHF(const Ref<KeyVal>&keyval):  PsiSCF(keyval){  if ((!docc_ || !socc_) && multp_ == 1) {    ExEnv::err0() << indent		  << "ERROR: PsiHSOSHF: multiplicity should be > 1 for HSOSHF wave function" << endl;    abort();  }}PsiHSOSHF::~PsiHSOSHF(){}PsiHSOSHF::PsiHSOSHF(StateIn&s):  PsiSCF(s){}voidPsiHSOSHF::write_basic_input(int convergence){  Ref<PsiInput> input = get_psi_input();  input->write_keyword("psi:reference","rohf");  if (docc_)    input->write_keyword_array("psi:docc",nirrep_,docc_);  if (socc_)    input->write_keyword_array("psi:socc",nirrep_,socc_);}voidPsiHSOSHF::write_input(int convergence){  Ref<PsiInput> input = get_psi_input();  input->open();  PsiWavefunction::write_basic_input(convergence);  write_basic_input(convergence);  input->write_keyword("psi:wfn","scf");  input->close();}//////////////////////////////////////////////////////////////////////////static ClassDesc PsiUHF_cd(  typeid(PsiUHF),"PsiUHF",1,"public PsiSCF",  0, create<PsiUHF>, create<PsiUHF>);PsiUHF::PsiUHF(const Ref<KeyVal>&keyval):  PsiSCF(keyval){}PsiUHF::~PsiUHF(){}PsiUHF::PsiUHF(StateIn&s):  PsiSCF(s){}voidPsiUHF::write_basic_input(int convergence){  Ref<PsiInput> input = get_psi_input();  input->write_keyword("psi:reference","uhf");  if (docc_)    input->write_keyword_array("psi:docc",nirrep_,docc_);  if (socc_)    input->write_keyword_array("psi:socc",nirrep_,socc_);}voidPsiUHF::write_input(int convergence){  Ref<PsiInput> input = get_psi_input();  input->open();  PsiWavefunction::write_basic_input(convergence);  write_basic_input(convergence);  input->write_keyword("psi:wfn","scf");  input->close();}//////////////////////////////////////////////////////////////////////////static ClassDesc PsiCCSD_cd(  typeid(PsiCCSD),"PsiCCSD",1,"public PsiWavefunction",  0, create<PsiCCSD>, create<PsiCCSD>);PsiCCSD::PsiCCSD(const Ref<KeyVal>&keyval):  PsiWavefunction(keyval){  reference_ << keyval->describedclassvalue("reference");  if (reference_.null()) {    ExEnv::err0() << "PsiCCSD::PsiCCSD: no reference wavefunction" << endl;    abort();  }}PsiCCSD::~PsiCCSD(){}PsiCCSD::PsiCCSD(StateIn&s):  PsiWavefunction(s){  reference_ << SavableState::restore_state(s);}intPsiCCSD::gradient_implemented() const{  int impl = 0;  PsiSCF::RefType reftype = reference_->reftype();  if (reftype == PsiSCF::rhf || reftype == PsiSCF::hsoshf)    impl = 1;  return impl;}voidPsiCCSD::save_data_state(StateOut&s){  PsiWavefunction::save_data_state(s);  SavableState::save_state(reference_.pointer(),s);}voidPsiCCSD::write_input(int convergence){  if (gradient_needed())    reference_->do_gradient(1);  else    reference_->do_gradient(0);      Ref<PsiInput> input = get_psi_input();  input->open();  PsiWavefunction::write_basic_input(convergence);  reference_->write_basic_input(convergence);  input->write_keyword("psi:wfn","ccsd");  if (frozen_docc_)    input->write_keyword_array("psi:frozen_docc",nirrep_,frozen_docc_);  if (frozen_uocc_)    input->write_keyword_array("psi:frozen_uocc",nirrep_,frozen_uocc_);  input->close();}//////////////////////////////////////////////////////////////////////////static ClassDesc PsiCCSD_T_cd(  typeid(PsiCCSD_T),"PsiCCSD_T",1,"public PsiWavefunction",  0, create<PsiCCSD_T>, create<PsiCCSD_T>);PsiCCSD_T::PsiCCSD_T(const Ref<KeyVal>&keyval):  PsiWavefunction(keyval){  reference_ << keyval->describedclassvalue("reference");  if (reference_.null()) {    ExEnv::err0() << "PsiCCSD_T::PsiCCSD_T: no reference wavefunction" << endl;    abort();  }  PsiSCF::RefType reftype = reference_->reftype();  if (reftype == PsiSCF::hsoshf) {    ExEnv::err0() << "PsiCCSD_T::PsiCCSD_T: HSOSHF-based CCSD(T) has not been implemented yet" << endl;    abort();  }}PsiCCSD_T::~PsiCCSD_T(){}PsiCCSD_T::PsiCCSD_T(StateIn&s):  PsiWavefunction(s){  reference_ << SavableState::restore_state(s);}intPsiCCSD_T::gradient_implemented() const{  int impl = 0;  PsiSCF::RefType reftype = reference_->reftype();  return impl;}voidPsiCCSD_T::save_data_state(StateOut&s){  PsiWavefunction::save_data_state(s);  SavableState::save_state(reference_.pointer(),s);}voidPsiCCSD_T::write_input(int convergence){  if (gradient_needed())    reference_->do_gradient(1);  else    reference_->do_gradient(0);      Ref<PsiInput> input = get_psi_input();  input->open();  PsiWavefunction::write_basic_input(convergence);  reference_->write_basic_input(convergence);  input->write_keyword("psi:wfn","ccsd");  input->begin_section("psi");  input->write_keyword("exec","(\"cints\" \"cscf\" \"transqt\" \"ccsort\" \"ccenergy\" \"cchbar\" \"cctriples\")");  input->end_section();  if (frozen_docc_)    input->write_keyword_array("psi:frozen_docc",nirrep_,frozen_docc_);  if (frozen_uocc_)    input->write_keyword_array("psi:frozen_uocc",nirrep_,frozen_uocc_);  input->close();}//////////////////////////////////////////////////////////////////////////}// Local Variables:// mode: c++// c-file-style: "CLJ"// End:

⌨️ 快捷键说明

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