00001
00008 #include <stdexcept>
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <math.h>
00012 extern "C" {
00013 #include <libciomr/libciomr.h>
00014 #include <libchkpt/chkpt.h>
00015 #include <psifiles.h>
00016 }
00017 #include "basisset.h"
00018
00019
00020 using namespace psi;
00021
00022 BasisSet::BasisSet(int chkptfile)
00023 {
00024 num_shells_ = chkpt_rd_nshell();
00025 num_prims_ = chkpt_rd_nprim();
00026 num_ao_ = chkpt_rd_nao();
00027
00028 num_bf_ = chkpt_rd_nso();
00029 puream_ = chkpt_rd_puream();
00030 max_am_ = chkpt_rd_max_am();
00031
00032 shells_ = new GaussianShell*[num_shells_];
00033
00034 init_shells();
00035
00036 }
00037
00038 BasisSet::BasisSet(const BasisSet& S) :
00039 num_prims_(S.num_prims_), num_shells_(S.num_shells_), num_ao_(S.num_ao_),
00040 num_bf_(S.num_bf_), max_am_(S.max_am_), puream_(S.puream_)
00041 {
00042 shells_ = new GaussianShell*[num_shells_];
00043 for(int s=0; s<num_shells_; s++)
00044 shells_[s] = new GaussianShell(*(S.shells_[s]));
00045
00046 ncenters_ = S.ncenters_;
00047 coords_ = block_matrix(ncenters_,3);
00048 for(int c=0; c<ncenters_; c++)
00049 for(int xyz=0; xyz<3; xyz++)
00050 coords_[c][xyz] = S.coords_[c][xyz];
00051
00052 shell_fbf_ = new int[num_shells_];
00053 shell_fao_ = new int[num_shells_];
00054 shell_center_ = new int[num_shells_];
00055 for(int s=0; s<num_shells_; s++) {
00056 shell_fbf_[s] = S.shell_fbf_[s];
00057 shell_fao_[s] = S.shell_fao_[s];
00058 shell_center_[s] = S.shell_center_[s];
00059 }
00060 }
00061
00062 BasisSet::~BasisSet()
00063 {
00064
00065 for(int s=0; s<num_shells_; s++)
00066 shells_[s]->~GaussianShell();
00067 delete[] shells_;
00068 free(shell_center_);
00069 free(shell_fao_);
00070 free(shell_fbf_);
00071 free_block(coords_);
00072 }
00073
00074 void BasisSet::init_shells()
00075 {
00076
00077 int *shell_am = chkpt_rd_stype();
00078
00079
00080 int *shell_num_prims = chkpt_rd_snumg();
00081
00082
00083 PSI_FLOAT *exponents = chkpt_rd_exps();
00084
00085
00086 PSI_FLOAT **ccoeffs = chkpt_rd_contr_full();
00087
00088
00089 int *shell_fprim = chkpt_rd_sprim();
00090
00091
00092 shell_fbf_ = chkpt_rd_sloc_new();
00093
00094
00095 shell_fao_ = chkpt_rd_sloc();
00096
00097
00098 shell_center_ = chkpt_rd_snuc();
00099
00100
00101 ncenters_ = chkpt_rd_natom();
00102
00103
00104 coords_ = chkpt_rd_geom();
00105
00106
00107 int ncontr = 1;
00108 int* am = new int[ncontr];
00109 for (int i=0; i<num_shells_; i++) {
00110 am[0] = shell_am[i]-1;
00111 int fprim = shell_fprim[i] - 1;
00112 int nprims = shell_num_prims[i];
00113 int center = shell_center_[i] - 1;
00114 PSI_FLOAT **cc = new PSI_FLOAT*[nprims];
00115 for(int p=0; p<nprims; p++) {
00116 cc[p] = new PSI_FLOAT[ncontr];
00117 cc[p][0] = ccoeffs[fprim+p][am[0]];
00118 }
00119 shells_[i] = new GaussianShell(nprims, ncontr, am, puream_, &(exponents[fprim]), cc, coords_[center]);
00120 for(int p=0; p<nprims; p++) {
00121 delete[] cc[p];
00122 }
00123 delete[] cc;
00124 }
00125
00126 free_block(ccoeffs);
00127 free(exponents);
00128 free(shell_am);
00129 free(shell_num_prims);
00130 free(shell_fprim);
00131 }
00132
00133 void BasisSet::check_shell_index(int si) const {
00134 if (si < 0 || si >= num_shells_)
00135 throw std::runtime_error("ERROR: BasisSet::check_shell_index -- shell index out of bounds");
00136 }
00137
00138 int BasisSet::num_prims() const { return num_prims_; };
00139 int BasisSet::num_shells() const { return num_shells_; };
00140 int BasisSet::num_ao() const { return num_ao_; };
00141 int BasisSet::num_bf() const { return num_bf_; };
00142 int BasisSet::max_am() const { return max_am_; };
00143
00144 GaussianShell& BasisSet::shell(int si) const
00145 {
00146 check_shell_index(si);
00147 return *(shells_[si]);
00148 };
00149
00150 int BasisSet::first_bf(int si) const
00151 {
00152 check_shell_index(si);
00153 return shell_fbf_[si] - 1;
00154 };
00155
00156 int BasisSet::first_ao(int si) const
00157 {
00158 check_shell_index(si);
00159 return shell_fao_[si] - 1;
00160 };
00161
00162 int BasisSet::center(int si) const
00163 {
00164 check_shell_index(si);
00165 return shell_center_[si] - 1;
00166 }
00167
00168 void BasisSet::set_center(int ci, PSI_FLOAT O[3])
00169 {
00170 for(int xyz=0; xyz<3; xyz++)
00171 coords_[ci][xyz] = O[xyz];
00172 for(int si=0; si<num_shells_; si++) {
00173 if (shell_center_[si] == ci + 1)
00174 shells_[si]->set_origin(O);
00175 }
00176 }
00177
00178 PSI_FLOAT BasisSet::get_center(int ci, int i)
00179 {
00180 return coords_[ci][i];
00181 }
00182
00183 void BasisSet::print(char *id, FILE* outfile) const {
00184 char indent1[] = " ";
00185 char indent2[] = " ";
00186
00187 fprintf(outfile, "%s-Basis Set %s\n",indent1,id);
00188 fprintf(outfile, "%sNumber of shells = %d\n",indent2,num_shells_);
00189 fprintf(outfile, "%sNumber of basis functions = %d\n",indent2,num_bf_);
00190 fprintf(outfile, "%sNumber of Cartesian Gaussians = %d\n",indent2,num_ao_);
00191 fprintf(outfile, "%sSpherical Harmonics? = %s\n",indent2,(puream_ ? "true" : "false"));
00192 fprintf(outfile, "%sMax angular momentum = %d\n\n",indent2,max_am_);
00193
00194 fprintf(outfile, "%sShells:\n\n",indent2);
00195 for(int s=0; s<num_shells_; s++)
00196 shells_[s]->print(s,outfile);
00197 }
00198