| [0b990d] | 1 | /*
 | 
|---|
 | 2 | **
 | 
|---|
 | 3 | ** PSI Input Class
 | 
|---|
 | 4 | **
 | 
|---|
 | 5 | ** This helper class will set up input decks for the PSI suite of
 | 
|---|
 | 6 | ** ab initio quantum chemistry programs.
 | 
|---|
 | 7 | **
 | 
|---|
 | 8 | ** David Sherrill & Justin Fermann
 | 
|---|
 | 9 | ** Center for Computational Quantum Chemistry, University of Georgia
 | 
|---|
 | 10 | **
 | 
|---|
 | 11 | */
 | 
|---|
 | 12 | 
 | 
|---|
 | 13 | #ifdef __GNUG__
 | 
|---|
 | 14 | #pragma implementation
 | 
|---|
 | 15 | #endif
 | 
|---|
 | 16 | 
 | 
|---|
 | 17 | #include <iostream>
 | 
|---|
 | 18 | #include <math.h>
 | 
|---|
 | 19 | 
 | 
|---|
 | 20 | #include <util/misc/string.h>
 | 
|---|
 | 21 | #include <util/misc/formio.h>
 | 
|---|
 | 22 | #include <math/symmetry/corrtab.h>
 | 
|---|
 | 23 | #include <chemistry/qc/wfn/obwfn.h>
 | 
|---|
 | 24 | #include <chemistry/molecule/molecule.h>
 | 
|---|
 | 25 | #include <chemistry/molecule/atominfo.h>
 | 
|---|
 | 26 | #include <chemistry/qc/basis/basis.h>
 | 
|---|
 | 27 | #include <chemistry/qc/basis/petite.h>
 | 
|---|
 | 28 | #include <chemistry/qc/psi/psiexenv.h>
 | 
|---|
 | 29 | #include <chemistry/qc/psi/psiinput.h>
 | 
|---|
 | 30 | 
 | 
|---|
 | 31 | using namespace std;
 | 
|---|
 | 32 | 
 | 
|---|
 | 33 | namespace sc {
 | 
|---|
 | 34 | 
 | 
|---|
 | 35 | PsiInput::PsiInput(const string& name) : file_()
 | 
|---|
 | 36 | {
 | 
|---|
 | 37 |   filename_ = string(name);
 | 
|---|
 | 38 |   indentation_ = 0;
 | 
|---|
 | 39 | }
 | 
|---|
 | 40 | 
 | 
|---|
 | 41 | PsiInput::~PsiInput()
 | 
|---|
 | 42 | {
 | 
|---|
 | 43 | }
 | 
|---|
 | 44 | 
 | 
|---|
 | 45 | void
 | 
|---|
 | 46 | PsiInput::open()
 | 
|---|
 | 47 | {
 | 
|---|
 | 48 |   file_.open(filename_.c_str(),ios::out);
 | 
|---|
 | 49 |   indentation_ = 0;
 | 
|---|
 | 50 | }
 | 
|---|
 | 51 | 
 | 
|---|
 | 52 | void
 | 
|---|
 | 53 | PsiInput::close()
 | 
|---|
 | 54 | {
 | 
|---|
 | 55 |   file_.close();
 | 
|---|
 | 56 |   indentation_ = 0;
 | 
|---|
 | 57 | }
 | 
|---|
 | 58 | 
 | 
|---|
 | 59 | 
 | 
|---|
 | 60 | void 
 | 
|---|
 | 61 | PsiInput::write_indent()
 | 
|---|
 | 62 | {
 | 
|---|
 | 63 |   for (int i=0; i<indentation_; i++)
 | 
|---|
 | 64 |     file_ << " ";
 | 
|---|
 | 65 | }
 | 
|---|
 | 66 | 
 | 
|---|
 | 67 | void
 | 
|---|
 | 68 | PsiInput::incindent(int i)
 | 
|---|
 | 69 | {
 | 
|---|
 | 70 |   if (i > 0)
 | 
|---|
 | 71 |     indentation_ += i;
 | 
|---|
 | 72 | }
 | 
|---|
 | 73 | 
 | 
|---|
 | 74 | void
 | 
|---|
 | 75 | PsiInput::decindent(int i)
 | 
|---|
 | 76 | {
 | 
|---|
 | 77 |   if (i > 0)
 | 
|---|
 | 78 |     indentation_ -= i;
 | 
|---|
 | 79 | }
 | 
|---|
 | 80 | 
 | 
|---|
 | 81 | void
 | 
|---|
 | 82 | PsiInput::begin_section(const char * s)
 | 
|---|
 | 83 | {
 | 
|---|
 | 84 |    write_indent();
 | 
|---|
 | 85 |    file_ << s << ":(" << endl;
 | 
|---|
 | 86 |    incindent(2);
 | 
|---|
 | 87 | }
 | 
|---|
 | 88 | 
 | 
|---|
 | 89 | void
 | 
|---|
 | 90 | PsiInput::end_section(void)
 | 
|---|
 | 91 | {
 | 
|---|
 | 92 |    decindent(2);
 | 
|---|
 | 93 |    write_indent();
 | 
|---|
 | 94 |    file_ << ")" << endl;
 | 
|---|
 | 95 |    write_string("\n");
 | 
|---|
 | 96 | }
 | 
|---|
 | 97 | 
 | 
|---|
 | 98 | void
 | 
|---|
 | 99 | PsiInput::write_keyword(const char *keyword, const char *value)
 | 
|---|
 | 100 | {
 | 
|---|
 | 101 |    write_indent();
 | 
|---|
 | 102 |    file_ << scprintf("%s = %s",keyword,value) << endl;
 | 
|---|
 | 103 | }
 | 
|---|
 | 104 | 
 | 
|---|
 | 105 | void
 | 
|---|
 | 106 | PsiInput::write_keyword(const char *keyword, int value)
 | 
|---|
 | 107 | {
 | 
|---|
 | 108 |    write_indent();
 | 
|---|
 | 109 |    file_ << scprintf("%s = %d",keyword,value) << endl;
 | 
|---|
 | 110 | }
 | 
|---|
 | 111 | 
 | 
|---|
 | 112 | void
 | 
|---|
 | 113 | PsiInput::write_keyword(const char *keyword, double value)
 | 
|---|
 | 114 | {
 | 
|---|
 | 115 |    write_indent();
 | 
|---|
 | 116 |    file_ << scprintf("%s = %20.15lf",keyword,value) << endl;
 | 
|---|
 | 117 | }
 | 
|---|
 | 118 | 
 | 
|---|
 | 119 | void
 | 
|---|
 | 120 | PsiInput::write_keyword_array(const char *keyword, int num, int *values)
 | 
|---|
 | 121 | {
 | 
|---|
 | 122 |   write_indent();
 | 
|---|
 | 123 |   file_ << scprintf("%s = (", keyword);
 | 
|---|
 | 124 |   for (int i=0; i<num; i++) {
 | 
|---|
 | 125 |     file_ << scprintf(" %d", values[i]);
 | 
|---|
 | 126 |   }
 | 
|---|
 | 127 |   file_ << ")" << endl;
 | 
|---|
 | 128 | }
 | 
|---|
 | 129 | 
 | 
|---|
 | 130 | void
 | 
|---|
 | 131 | PsiInput::write_keyword_array(const char *keyword, int num, double *values)
 | 
|---|
 | 132 | {
 | 
|---|
 | 133 |    write_indent();
 | 
|---|
 | 134 |    file_ << scprintf("%s = (", keyword);
 | 
|---|
 | 135 |   for (int i=0; i<num; i++) {
 | 
|---|
 | 136 |     file_ << scprintf(" %20.15lf", values[i]);
 | 
|---|
 | 137 |   }
 | 
|---|
 | 138 |   file_ << ")" << endl;
 | 
|---|
 | 139 | }
 | 
|---|
 | 140 | 
 | 
|---|
 | 141 | void 
 | 
|---|
 | 142 | PsiInput::write_string(const char *s)
 | 
|---|
 | 143 | {
 | 
|---|
 | 144 |    write_indent();
 | 
|---|
 | 145 |    file_ << s;
 | 
|---|
 | 146 | }
 | 
|---|
 | 147 | 
 | 
|---|
 | 148 | void
 | 
|---|
 | 149 | PsiInput::write_key_wq(const char *keyword, const char *value)
 | 
|---|
 | 150 | {
 | 
|---|
 | 151 |    write_indent();
 | 
|---|
 | 152 |    file_ << scprintf("%s = \"%s\"", keyword, value) << endl;
 | 
|---|
 | 153 | }
 | 
|---|
 | 154 | 
 | 
|---|
 | 155 | 
 | 
|---|
 | 156 | void
 | 
|---|
 | 157 | PsiInput::write_geom(const Ref<Molecule>& mol)
 | 
|---|
 | 158 | {
 | 
|---|
 | 159 |   // If the highest symmetry group is not the actual group - use subgroup keyword
 | 
|---|
 | 160 |   if (!mol->point_group()->equiv(mol->highest_point_group())) {
 | 
|---|
 | 161 |     write_keyword("subgroup",mol->point_group()->symbol());
 | 
|---|
 | 162 |   }
 | 
|---|
 | 163 | 
 | 
|---|
 | 164 |   write_keyword("units","bohr");
 | 
|---|
 | 165 |   write_string("geometry = (\n");
 | 
|---|
 | 166 |   for (int i=0; i < mol->natom(); i++) {
 | 
|---|
 | 167 |     write_string("  (");
 | 
|---|
 | 168 |     char *s;
 | 
|---|
 | 169 |     file_ << mol->atom_symbol(i) <<
 | 
|---|
 | 170 |         scprintf(" %14.12lf %14.12lf %14.12lf",mol->r(i,0),mol->r(i,1),mol->r(i,2))
 | 
|---|
 | 171 |           << ")" << endl;
 | 
|---|
 | 172 |   } 
 | 
|---|
 | 173 |   write_string(")\n");
 | 
|---|
 | 174 | }
 | 
|---|
 | 175 | 
 | 
|---|
 | 176 | 
 | 
|---|
 | 177 | void
 | 
|---|
 | 178 | PsiInput::write_basis(const Ref<GaussianBasisSet>& basis)
 | 
|---|
 | 179 | {
 | 
|---|
 | 180 |   Ref<Molecule> molecule = basis->molecule();
 | 
|---|
 | 181 |   int natom = molecule->natom();
 | 
|---|
 | 182 | 
 | 
|---|
 | 183 |   write_string("basis = (\n");
 | 
|---|
 | 184 |   incindent(2);
 | 
|---|
 | 185 |   for(int atom=0; atom<natom; atom++) {
 | 
|---|
 | 186 |     int uatom = molecule->atom_to_unique(atom);
 | 
|---|
 | 187 | 
 | 
|---|
 | 188 |     // Replace all spaces with underscores in order for Psi libipv1 to parse properly
 | 
|---|
 | 189 |     char *name = strdup(basis->name());
 | 
|---|
 | 190 |     int len = strlen(name);
 | 
|---|
 | 191 |     for (int i=0; i<len; i++)
 | 
|---|
 | 192 |       if (name[i] == ' ')
 | 
|---|
 | 193 |         name[i] = '_';
 | 
|---|
 | 194 | 
 | 
|---|
 | 195 |     char *basisname = new char[strlen(basis->name()) + ((int)ceil(log10((long double)uatom+2))) + 5];
 | 
|---|
 | 196 |     sprintf(basisname,"\"%s%d\" \n",name,uatom);
 | 
|---|
 | 197 |     write_string(basisname);
 | 
|---|
 | 198 |     delete[] name;
 | 
|---|
 | 199 |   }
 | 
|---|
 | 200 |   decindent(2);
 | 
|---|
 | 201 |   write_string(")\n");
 | 
|---|
 | 202 | }
 | 
|---|
 | 203 | 
 | 
|---|
 | 204 | void
 | 
|---|
 | 205 | PsiInput::write_basis_sets(const Ref<GaussianBasisSet>& basis)
 | 
|---|
 | 206 | {
 | 
|---|
 | 207 |   begin_section("basis");
 | 
|---|
 | 208 |   Ref<Molecule> molecule = basis->molecule();
 | 
|---|
 | 209 |   Ref<AtomInfo> atominfo = basis->molecule()->atominfo();
 | 
|---|
 | 210 |   int nunique = molecule->nunique();
 | 
|---|
 | 211 | 
 | 
|---|
 | 212 |   for(int uatom=0; uatom<nunique; uatom++) {
 | 
|---|
 | 213 |     int atom = molecule->unique(uatom);
 | 
|---|
 | 214 |     std::string atomname = atominfo->name(molecule->Z(atom));
 | 
|---|
 | 215 | 
 | 
|---|
 | 216 |     // Replace all spaces with underscores in order for Psi libipv1 to parse properly
 | 
|---|
 | 217 |     char *name = strdup(basis->name());
 | 
|---|
 | 218 |     int len = strlen(name);
 | 
|---|
 | 219 |     for (int i=0; i<len; i++)
 | 
|---|
 | 220 |       if (name[i] == ' ')
 | 
|---|
 | 221 |         name[i] = '_';
 | 
|---|
 | 222 | 
 | 
|---|
 | 223 |     char *psibasisname = new char[atomname.size() + strlen(basis->name()) + ((int)ceil(log10((long double)uatom+2))) + 9];
 | 
|---|
 | 224 |     sprintf(psibasisname,"%s:\"%s%d\" = (\n",atomname.c_str(),name,uatom);
 | 
|---|
 | 225 |     write_string(psibasisname);
 | 
|---|
 | 226 |     delete[] name;
 | 
|---|
 | 227 |     incindent(2);
 | 
|---|
 | 228 |     int nshell = basis->nshell_on_center(atom);
 | 
|---|
 | 229 |     for(int sh=0;sh<nshell;sh++) {
 | 
|---|
 | 230 |       int shell = basis->shell_on_center(atom,sh);
 | 
|---|
 | 231 |       GaussianShell& Shell = basis->shell(shell);
 | 
|---|
 | 232 |       int ncon = Shell.ncontraction();
 | 
|---|
 | 233 |       int nprim = Shell.nprimitive();
 | 
|---|
 | 234 |       for(int con=0; con<ncon; con++) {
 | 
|---|
 | 235 |         char amstring[4];
 | 
|---|
 | 236 |         sprintf(amstring,"(%c\n",Shell.amchar(con));
 | 
|---|
 | 237 |         write_string(amstring);
 | 
|---|
 | 238 |         incindent(2);
 | 
|---|
 | 239 |         for(int prim=0; prim<nprim; prim++) {
 | 
|---|
 | 240 |           char primstring[50];
 | 
|---|
 | 241 |           sprintf(primstring,"(%20.10lf    %20.10lf)\n",
 | 
|---|
 | 242 |                   Shell.exponent(prim),
 | 
|---|
 | 243 |                   Shell.coefficient_norm(con,prim));
 | 
|---|
 | 244 |           write_string(primstring);
 | 
|---|
 | 245 |         }
 | 
|---|
 | 246 |         decindent(2);
 | 
|---|
 | 247 |         write_string(")\n");
 | 
|---|
 | 248 |       }
 | 
|---|
 | 249 |     }
 | 
|---|
 | 250 |     decindent(2);
 | 
|---|
 | 251 |     write_string(")\n");
 | 
|---|
 | 252 |     delete[] psibasisname;
 | 
|---|
 | 253 |   }
 | 
|---|
 | 254 |   end_section();
 | 
|---|
 | 255 | }
 | 
|---|
 | 256 | 
 | 
|---|
 | 257 | void
 | 
|---|
 | 258 | PsiInput::write_defaults(const Ref<PsiExEnv>& exenv, const char *dertype)
 | 
|---|
 | 259 | {
 | 
|---|
 | 260 |   begin_section("psi");
 | 
|---|
 | 261 |   
 | 
|---|
 | 262 |   write_key_wq("label"," ");
 | 
|---|
 | 263 |   write_keyword("dertype",dertype);
 | 
|---|
 | 264 |   begin_section("files");
 | 
|---|
 | 265 |   begin_section("default");
 | 
|---|
 | 266 |   write_key_wq("name",(exenv->get_fileprefix()).c_str());
 | 
|---|
 | 267 |   int nscratch = exenv->get_nscratch();
 | 
|---|
 | 268 |   write_keyword("nvolume",nscratch);
 | 
|---|
 | 269 |   char *scrname; scrname = new char[10];
 | 
|---|
 | 270 |   for(int i=0; i<nscratch; i++) {
 | 
|---|
 | 271 |     sprintf(scrname,"volume%d",i+1);
 | 
|---|
 | 272 |     write_key_wq(scrname,(exenv->get_scratch(i)).c_str());
 | 
|---|
 | 273 |   }
 | 
|---|
 | 274 |   delete[] scrname;
 | 
|---|
 | 275 |   end_section();
 | 
|---|
 | 276 |   write_string("file32: ( nvolume = 1 volume1 = \"./\" )\n");
 | 
|---|
 | 277 |   end_section();
 | 
|---|
 | 278 | 
 | 
|---|
 | 279 |   end_section();
 | 
|---|
 | 280 | }
 | 
|---|
 | 281 | 
 | 
|---|
 | 282 | 
 | 
|---|
 | 283 | void
 | 
|---|
 | 284 | PsiInput::print(ostream& o)
 | 
|---|
 | 285 | {
 | 
|---|
 | 286 | }
 | 
|---|
 | 287 | 
 | 
|---|
 | 288 | }
 | 
|---|