| [5d30c1] | 1 | //
 | 
|---|
 | 2 | // mpqc.cc
 | 
|---|
 | 3 | //
 | 
|---|
 | 4 | // Copyright (C) 1996 Limit Point Systems, Inc.
 | 
|---|
 | 5 | //
 | 
|---|
 | 6 | // Author: Edward Seidl <seidl@janed.com>
 | 
|---|
 | 7 | // Maintainer: LPS
 | 
|---|
 | 8 | //
 | 
|---|
 | 9 | // This file is part of MPQC.
 | 
|---|
 | 10 | //
 | 
|---|
 | 11 | // MPQC is free software; you can redistribute it and/or modify
 | 
|---|
 | 12 | // it under the terms of the GNU General Public License as published by
 | 
|---|
 | 13 | // the Free Software Foundation; either version 2, or (at your option)
 | 
|---|
 | 14 | // any later version.
 | 
|---|
 | 15 | //
 | 
|---|
 | 16 | // MPQC is distributed in the hope that it will be useful,
 | 
|---|
 | 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
 | 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
 | 19 | // GNU General Public License for more details.
 | 
|---|
 | 20 | //
 | 
|---|
 | 21 | // You should have received a copy of the GNU General Public License
 | 
|---|
 | 22 | // along with the MPQC; see the file COPYING.  If not, write to
 | 
|---|
 | 23 | // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
|---|
 | 24 | //
 | 
|---|
 | 25 | // The U.S. Government is granted a limited license as per AL 91-7.
 | 
|---|
 | 26 | //
 | 
|---|
 | 27 | 
 | 
|---|
 | 28 | // This is needed to make GNU extensions available, such as
 | 
|---|
 | 29 | // feenableexcept and fedisableexcept.
 | 
|---|
 | 30 | #ifndef _GNU_SOURCE
 | 
|---|
 | 31 | #  define _GNU_SOURCE
 | 
|---|
 | 32 | #endif
 | 
|---|
 | 33 | 
 | 
|---|
 | 34 | #ifdef HAVE_CONFIG_H
 | 
|---|
 | 35 | #include <scconfig.h>
 | 
|---|
 | 36 | #endif
 | 
|---|
 | 37 | 
 | 
|---|
 | 38 | #ifdef HAVE_TIME_H
 | 
|---|
 | 39 | #include <time.h>
 | 
|---|
 | 40 | #endif
 | 
|---|
 | 41 | 
 | 
|---|
 | 42 | #include <scdirlist.h>
 | 
|---|
 | 43 | 
 | 
|---|
 | 44 | #include <new>
 | 
|---|
 | 45 | #include <stdexcept>
 | 
|---|
 | 46 | #include <string.h>
 | 
|---|
 | 47 | #include <unistd.h>
 | 
|---|
 | 48 | #include <sys/stat.h>
 | 
|---|
 | 49 | #include <fstream>
 | 
|---|
 | 50 | 
 | 
|---|
| [62dabe] | 51 | #include <boost/bind.hpp>
 | 
|---|
 | 52 | #include <boost/function.hpp>
 | 
|---|
 | 53 | 
 | 
|---|
| [5d30c1] | 54 | #include <scconfig.h>
 | 
|---|
 | 55 | #ifdef HAVE_SSTREAM
 | 
|---|
 | 56 | #  include <sstream>
 | 
|---|
 | 57 | #else
 | 
|---|
 | 58 | #  include <strstream.h>
 | 
|---|
 | 59 | #endif
 | 
|---|
 | 60 | 
 | 
|---|
 | 61 | #ifdef HAVE_SYS_RESOURCE_H
 | 
|---|
 | 62 | #  include <sys/resource.h>
 | 
|---|
 | 63 | #endif
 | 
|---|
 | 64 | #ifdef HAVE_SYS_TIME_H
 | 
|---|
 | 65 | #  include <sys/time.h>
 | 
|---|
 | 66 | #endif
 | 
|---|
 | 67 | 
 | 
|---|
 | 68 | #include <util/options/GetLongOpt.h>
 | 
|---|
 | 69 | #include <util/class/scexception.h>
 | 
|---|
 | 70 | #include <util/misc/newstring.h>
 | 
|---|
 | 71 | #include <util/keyval/keyval.h>
 | 
|---|
 | 72 | #include <util/state/state_bin.h>
 | 
|---|
 | 73 | #include <util/group/message.h>
 | 
|---|
 | 74 | #include <util/group/memory.h>
 | 
|---|
 | 75 | #include <util/group/mstate.h>
 | 
|---|
 | 76 | #include <util/group/thread.h>
 | 
|---|
 | 77 | #include <util/group/pregtime.h>
 | 
|---|
 | 78 | #include <util/misc/bug.h>
 | 
|---|
 | 79 | #include <util/misc/formio.h>
 | 
|---|
 | 80 | #include <util/misc/exenv.h>
 | 
|---|
 | 81 | #ifdef HAVE_CHEMISTRY_CCA
 | 
|---|
 | 82 |   #include <util/misc/ccaenv.h>
 | 
|---|
 | 83 | #endif
 | 
|---|
 | 84 | #include <util/render/render.h>
 | 
|---|
 | 85 | 
 | 
|---|
 | 86 | #include <math/optimize/opt.h>
 | 
|---|
 | 87 | 
 | 
|---|
 | 88 | #include <chemistry/molecule/coor.h>
 | 
|---|
 | 89 | #include <chemistry/molecule/energy.h>
 | 
|---|
 | 90 | #include <chemistry/molecule/molfreq.h>
 | 
|---|
 | 91 | #include <chemistry/molecule/fdhess.h>
 | 
|---|
 | 92 | #include <chemistry/molecule/formula.h>
 | 
|---|
 | 93 | #include <chemistry/qc/wfn/wfn.h>
 | 
|---|
 | 94 | 
 | 
|---|
 | 95 | // Force linkages:
 | 
|---|
 | 96 | #include <util/group/linkage.h>
 | 
|---|
 | 97 | #include <chemistry/qc/wfn/linkage.h>
 | 
|---|
 | 98 | #include <chemistry/qc/scf/linkage.h>
 | 
|---|
 | 99 | #include <chemistry/qc/dft/linkage.h>
 | 
|---|
 | 100 | #include <chemistry/qc/mbpt/linkage.h>
 | 
|---|
 | 101 | #ifdef HAVE_SC_SRC_LIB_CHEMISTRY_QC_MBPTR12
 | 
|---|
 | 102 | #  include <chemistry/qc/mbptr12/linkage.h>
 | 
|---|
 | 103 | #endif
 | 
|---|
 | 104 | #ifdef HAVE_SC_SRC_LIB_CHEMISTRY_QC_CINTS
 | 
|---|
 | 105 | #  include <chemistry/qc/cints/linkage.h>
 | 
|---|
 | 106 | #endif
 | 
|---|
 | 107 | //#include <chemistry/qc/psi/linkage.h>
 | 
|---|
 | 108 | #include <util/state/linkage.h>
 | 
|---|
 | 109 | #ifdef HAVE_SC_SRC_LIB_CHEMISTRY_QC_CC
 | 
|---|
 | 110 | #  include <chemistry/qc/cc/linkage.h>
 | 
|---|
 | 111 | #endif
 | 
|---|
 | 112 | #ifdef HAVE_SC_SRC_LIB_CHEMISTRY_QC_PSI
 | 
|---|
 | 113 | #  include <chemistry/qc/psi/linkage.h>
 | 
|---|
 | 114 | #endif
 | 
|---|
 | 115 | #ifdef HAVE_SC_SRC_LIB_CHEMISTRY_QC_INTCCA
 | 
|---|
 | 116 | #  include <chemistry/qc/intcca/linkage.h>
 | 
|---|
 | 117 | #endif
 | 
|---|
 | 118 | 
 | 
|---|
 | 119 | #ifdef HAVE_MPI
 | 
|---|
 | 120 | #define MPICH_SKIP_MPICXX
 | 
|---|
 | 121 | #include <mpi.h>
 | 
|---|
 | 122 | #include <util/group/messmpi.h>
 | 
|---|
 | 123 | #endif
 | 
|---|
 | 124 | 
 | 
|---|
| [035791] | 125 | #ifdef HAVE_JOBMARKET
 | 
|---|
 | 126 | // include headers that implement a archive in simple text format
 | 
|---|
 | 127 | // otherwise BOOST_CLASS_EXPORT_IMPLEMENT has no effect
 | 
|---|
 | 128 | #include <boost/archive/text_oarchive.hpp>
 | 
|---|
 | 129 | #include <boost/archive/text_iarchive.hpp>
 | 
|---|
 | 130 | #include <boost/bind.hpp>
 | 
|---|
 | 131 | #include <boost/tokenizer.hpp>
 | 
|---|
 | 132 | 
 | 
|---|
 | 133 | #include "JobMarket/Results/FragmentResult.hpp"
 | 
|---|
 | 134 | #include "JobMarket/poolworker_main.hpp"
 | 
|---|
 | 135 | 
 | 
|---|
| [16135f] | 136 | #include "chemistry/qc/scf/scfops.h"
 | 
|---|
 | 137 | 
 | 
|---|
| [850bce] | 138 | #ifdef HAVE_MPQCDATA
 | 
|---|
| [5ce17f] | 139 | #include "Jobs/MPQCJob.hpp"
 | 
|---|
| [16135f] | 140 | #include "Jobs/MPQCData.hpp"
 | 
|---|
| [1ed5fc] | 141 | 
 | 
|---|
 | 142 | #include <chemistry/qc/basis/obint.h>
 | 
|---|
 | 143 | #include <chemistry/qc/basis/symmint.h>
 | 
|---|
| [850bce] | 144 | #endif
 | 
|---|
 | 145 | 
 | 
|---|
| [035791] | 146 | #include <algorithm>
 | 
|---|
 | 147 | #include <stdlib.h>
 | 
|---|
 | 148 | #endif
 | 
|---|
 | 149 | 
 | 
|---|
| [5d30c1] | 150 | using namespace std;
 | 
|---|
 | 151 | using namespace sc;
 | 
|---|
 | 152 | 
 | 
|---|
 | 153 | #include "mpqcin.h"
 | 
|---|
 | 154 | 
 | 
|---|
 | 155 | //////////////////////////////////////////////////////////////////////////
 | 
|---|
 | 156 | 
 | 
|---|
| [a8458d] | 157 | const KeyValValueboolean truevalue(1), falsevalue(0);
 | 
|---|
| [dca43b] | 158 | const char *devnull = "/dev/null";
 | 
|---|
| [a8458d] | 159 | 
 | 
|---|
 | 160 | 
 | 
|---|
| [5d30c1] | 161 | static void
 | 
|---|
 | 162 | trash_stack_b(int &i, char *&ichar)
 | 
|---|
 | 163 | {
 | 
|---|
 | 164 |   char stack;
 | 
|---|
 | 165 |   ichar = &stack;
 | 
|---|
 | 166 |   ichar -= 10;
 | 
|---|
 | 167 |   for (i=0; i<1000; i++) {
 | 
|---|
 | 168 |     *ichar-- = 0xfe;
 | 
|---|
 | 169 |   }
 | 
|---|
 | 170 | }
 | 
|---|
 | 171 | 
 | 
|---|
 | 172 | static void
 | 
|---|
 | 173 | trash_stack()
 | 
|---|
 | 174 | {
 | 
|---|
 | 175 |   int i;
 | 
|---|
 | 176 |   char *ichar;
 | 
|---|
 | 177 |   trash_stack_b(i,ichar);
 | 
|---|
 | 178 | }
 | 
|---|
 | 179 | 
 | 
|---|
 | 180 | static void
 | 
|---|
 | 181 | clean_up(void)
 | 
|---|
 | 182 | {
 | 
|---|
 | 183 |   MemoryGrp::set_default_memorygrp(0);
 | 
|---|
 | 184 |   ThreadGrp::set_default_threadgrp(0);
 | 
|---|
 | 185 |   SCMatrixKit::set_default_matrixkit(0);
 | 
|---|
 | 186 |   Integral::set_default_integral(0);
 | 
|---|
 | 187 |   RegionTimer::set_default_regiontimer(0);
 | 
|---|
 | 188 | }
 | 
|---|
 | 189 | 
 | 
|---|
| [4aba27] | 190 | static void
 | 
|---|
 | 191 | final_clean_up(void)
 | 
|---|
 | 192 | {
 | 
|---|
 | 193 |   MessageGrp::set_default_messagegrp(0);
 | 
|---|
 | 194 | }
 | 
|---|
 | 195 | 
 | 
|---|
| [5d30c1] | 196 | #include <signal.h>
 | 
|---|
 | 197 | 
 | 
|---|
 | 198 | #ifdef HAVE_FENV_H
 | 
|---|
 | 199 | #  include <fenv.h>
 | 
|---|
 | 200 | #endif
 | 
|---|
 | 201 | 
 | 
|---|
 | 202 | static void
 | 
|---|
 | 203 | print_unseen(const Ref<ParsedKeyVal> &parsedkv,
 | 
|---|
 | 204 |              const char *input)
 | 
|---|
 | 205 | {
 | 
|---|
 | 206 |   if (parsedkv->have_unseen()) {
 | 
|---|
 | 207 |     ExEnv::out0() << endl;
 | 
|---|
 | 208 |     ExEnv::out0() << indent
 | 
|---|
 | 209 |          << "The following keywords in \"" << input << "\" were ignored:"
 | 
|---|
 | 210 |          << endl;
 | 
|---|
 | 211 |     ExEnv::out0() << incindent;
 | 
|---|
 | 212 |     parsedkv->print_unseen(ExEnv::out0());
 | 
|---|
 | 213 |     ExEnv::out0() << decindent;
 | 
|---|
 | 214 |   }
 | 
|---|
 | 215 | }
 | 
|---|
 | 216 | 
 | 
|---|
| [62dabe] | 217 | double EvaluateDensity(
 | 
|---|
 | 218 |     SCVector3 &r,
 | 
|---|
 | 219 |     Ref<Integral> &intgrl,
 | 
|---|
 | 220 |     GaussianBasisSet::ValueData &vdat,
 | 
|---|
 | 221 |     Ref<Wavefunction> &wfn);
 | 
|---|
 | 222 | 
 | 
|---|
 | 223 | /** Places all known options into \a options and parses them from argc,argv.
 | 
|---|
 | 224 |  *
 | 
|---|
 | 225 |  * \param options options structure
 | 
|---|
 | 226 |  * \param argc argument count
 | 
|---|
 | 227 |  * \param argv argument array
 | 
|---|
 | 228 |  * \return return value by GetLongOpt::parse() function
 | 
|---|
 | 229 |  */
 | 
|---|
| [36d8ab] | 230 | int ParseOptions(
 | 
|---|
 | 231 |     GetLongOpt &options,
 | 
|---|
 | 232 |     int argc,
 | 
|---|
 | 233 |     char **argv)
 | 
|---|
| [5d30c1] | 234 | {
 | 
|---|
 | 235 |   options.usage("[options] [filename]");
 | 
|---|
 | 236 |   options.enroll("f", GetLongOpt::MandatoryValue,
 | 
|---|
 | 237 |                  "the name of an object format input file", 0);
 | 
|---|
 | 238 |   options.enroll("o", GetLongOpt::MandatoryValue,
 | 
|---|
 | 239 |                  "the name of the output file", 0);
 | 
|---|
| [035791] | 240 |   options.enroll("n", GetLongOpt::MandatoryValue,
 | 
|---|
| [31c708] | 241 |                  "listen for incoming object format input files", 0);
 | 
|---|
| [5d30c1] | 242 |   options.enroll("messagegrp", GetLongOpt::MandatoryValue,
 | 
|---|
 | 243 |                  "which message group to use", 0);
 | 
|---|
 | 244 |   options.enroll("threadgrp", GetLongOpt::MandatoryValue,
 | 
|---|
 | 245 |                  "which thread group to use", 0);
 | 
|---|
 | 246 |   options.enroll("memorygrp", GetLongOpt::MandatoryValue,
 | 
|---|
 | 247 |                  "which memory group to use", 0);
 | 
|---|
 | 248 |   options.enroll("integral", GetLongOpt::MandatoryValue,
 | 
|---|
 | 249 |                  "which integral evaluator to use", 0);
 | 
|---|
 | 250 |   options.enroll("l", GetLongOpt::MandatoryValue, "basis set limit", "0");
 | 
|---|
 | 251 |   options.enroll("W", GetLongOpt::MandatoryValue,
 | 
|---|
 | 252 |                  "set the working directory", ".");
 | 
|---|
 | 253 |   options.enroll("c", GetLongOpt::NoValue, "check input then exit", 0);
 | 
|---|
 | 254 |   options.enroll("v", GetLongOpt::NoValue, "print the version number", 0);
 | 
|---|
 | 255 |   options.enroll("w", GetLongOpt::NoValue, "print the warranty", 0);
 | 
|---|
 | 256 |   options.enroll("L", GetLongOpt::NoValue, "print the license", 0);
 | 
|---|
 | 257 |   options.enroll("k", GetLongOpt::NoValue, "print key/value assignments", 0);
 | 
|---|
 | 258 |   options.enroll("i", GetLongOpt::NoValue, "convert simple to OO input", 0);
 | 
|---|
 | 259 |   options.enroll("d", GetLongOpt::NoValue, "debug", 0);
 | 
|---|
 | 260 |   options.enroll("h", GetLongOpt::NoValue, "print this message", 0);
 | 
|---|
| [62dabe] | 261 |   options.enroll("cca-path", GetLongOpt::OptionalValue,
 | 
|---|
| [5d30c1] | 262 |                  "cca component path", "");
 | 
|---|
 | 263 |   options.enroll("cca-load", GetLongOpt::OptionalValue,
 | 
|---|
 | 264 |                  "cca components to load", "");
 | 
|---|
 | 265 | 
 | 
|---|
 | 266 |   int optind = options.parse(argc, argv);
 | 
|---|
 | 267 | 
 | 
|---|
| [62dabe] | 268 |   return optind;
 | 
|---|
 | 269 | }
 | 
|---|
 | 270 | 
 | 
|---|
 | 271 | /** Checks for each known option and acts accordingly.
 | 
|---|
 | 272 |  *
 | 
|---|
 | 273 |  * \param options option structure
 | 
|---|
 | 274 |  * \param *output name of outputfile on return
 | 
|---|
 | 275 |  * \param *outstream open output stream on return
 | 
|---|
 | 276 |  */
 | 
|---|
| [36d8ab] | 277 | void ComputeOptions(
 | 
|---|
 | 278 |     GetLongOpt &options,
 | 
|---|
 | 279 |     const char *&output,
 | 
|---|
 | 280 |     ostream *&outstream)
 | 
|---|
| [62dabe] | 281 | {
 | 
|---|
 | 282 |   output = options.retrieve("o");
 | 
|---|
 | 283 |   outstream = 0;
 | 
|---|
| [5d30c1] | 284 |   if (output != 0) {
 | 
|---|
 | 285 |     outstream = new ofstream(output);
 | 
|---|
 | 286 |     ExEnv::set_out(outstream);
 | 
|---|
 | 287 |   }
 | 
|---|
 | 288 | 
 | 
|---|
 | 289 |   if (options.retrieve("h")) {
 | 
|---|
 | 290 |     ExEnv::out0()
 | 
|---|
 | 291 |          << indent << "MPQC version " << SC_VERSION << endl
 | 
|---|
 | 292 |          << indent << "compiled for " << TARGET_ARCH << endl
 | 
|---|
 | 293 |          << SCFormIO::copyright << endl;
 | 
|---|
 | 294 |     options.usage(ExEnv::out0());
 | 
|---|
 | 295 |     exit(0);
 | 
|---|
 | 296 |   }
 | 
|---|
| [62dabe] | 297 | 
 | 
|---|
| [5d30c1] | 298 |   if (options.retrieve("v")) {
 | 
|---|
 | 299 |     ExEnv::out0()
 | 
|---|
 | 300 |          << indent << "MPQC version " << SC_VERSION << endl
 | 
|---|
 | 301 |          << indent << "compiled for " << TARGET_ARCH << endl
 | 
|---|
 | 302 |          << SCFormIO::copyright;
 | 
|---|
 | 303 |     exit(0);
 | 
|---|
 | 304 |   }
 | 
|---|
| [62dabe] | 305 | 
 | 
|---|
| [5d30c1] | 306 |   if (options.retrieve("w")) {
 | 
|---|
 | 307 |     ExEnv::out0()
 | 
|---|
 | 308 |          << indent << "MPQC version " << SC_VERSION << endl
 | 
|---|
 | 309 |          << indent << "compiled for " << TARGET_ARCH << endl
 | 
|---|
 | 310 |          << SCFormIO::copyright << endl
 | 
|---|
 | 311 |          << SCFormIO::warranty;
 | 
|---|
 | 312 |     exit(0);
 | 
|---|
 | 313 |   }
 | 
|---|
| [62dabe] | 314 | 
 | 
|---|
| [5d30c1] | 315 |   if (options.retrieve("L")) {
 | 
|---|
 | 316 |     ExEnv::out0()
 | 
|---|
 | 317 |          << indent << "MPQC version " << SC_VERSION << endl
 | 
|---|
 | 318 |          << indent << "compiled for " << TARGET_ARCH << endl
 | 
|---|
 | 319 |          << SCFormIO::copyright << endl
 | 
|---|
 | 320 |          << SCFormIO::license;
 | 
|---|
 | 321 |     exit(0);
 | 
|---|
 | 322 |   }
 | 
|---|
 | 323 | 
 | 
|---|
| [8860a6] | 324 |   if (options.retrieve("d"))
 | 
|---|
 | 325 |     SCFormIO::set_debug(1);
 | 
|---|
 | 326 | 
 | 
|---|
| [5d30c1] | 327 |   // set the working dir
 | 
|---|
 | 328 |   if (strcmp(options.retrieve("W"),"."))
 | 
|---|
| [62dabe] | 329 |     int retval = chdir(options.retrieve("W"));
 | 
|---|
| [5d30c1] | 330 | 
 | 
|---|
| [31c708] | 331 |   // check that n and f/o are not given at the same time
 | 
|---|
 | 332 |   if ((options.retrieve("n")) && ((options.retrieve("f")) || (options.retrieve("o")))) {
 | 
|---|
 | 333 |     throw invalid_argument("-n must not be given with -f or -o");
 | 
|---|
 | 334 |   }
 | 
|---|
| [62dabe] | 335 | }
 | 
|---|
 | 336 | 
 | 
|---|
| [ec4b04] | 337 | /** Temporary structure for storing information from command-line
 | 
|---|
 | 338 |  *
 | 
|---|
 | 339 |  * This structure has been introduced to gather the various calls to GetLongOpts
 | 
|---|
 | 340 |  * at one (initial) place and to abstract it from the source of command-lines.
 | 
|---|
 | 341 |  * This temporary object can be set by other means, too. I.e. we become
 | 
|---|
 | 342 |  * independent of usage in command-line programs.
 | 
|---|
 | 343 |  */
 | 
|---|
 | 344 | struct OptionValues {
 | 
|---|
 | 345 |   const char *keyvalue; // option "k"
 | 
|---|
 | 346 |   const char *debug; // option ""
 | 
|---|
 | 347 |   int limit; // option "l"
 | 
|---|
 | 348 |   const char *check; // option "c"
 | 
|---|
 | 349 |   const char *simple_input; // option "i"
 | 
|---|
| [52aacc] | 350 |   string executablename;
 | 
|---|
| [ec4b04] | 351 | 
 | 
|---|
 | 352 | #ifdef HAVE_CHEMISTRY_CCA
 | 
|---|
 | 353 |   string cca_load;  // option "cca-path"
 | 
|---|
 | 354 |   string cc_path; // option "cca-load"
 | 
|---|
 | 355 | #endif
 | 
|---|
 | 356 | };
 | 
|---|
 | 357 | 
 | 
|---|
 | 358 | /** Parse remainder options not treated by ComputeOptions() into temporary storage.
 | 
|---|
 | 359 |  *
 | 
|---|
 | 360 |  * \param options option structure to obtain values from
 | 
|---|
 | 361 |  * \param values remaining option values which are processed later and now
 | 
|---|
 | 362 |  *        stored in a temporary structure
 | 
|---|
 | 363 |  */
 | 
|---|
 | 364 | void parseRemainderOptions(
 | 
|---|
 | 365 |     GetLongOpt &options,
 | 
|---|
| [52aacc] | 366 |     struct OptionValues &values,
 | 
|---|
 | 367 |     int argc,
 | 
|---|
 | 368 |     char **argv)
 | 
|---|
| [ec4b04] | 369 | {
 | 
|---|
 | 370 |   values.keyvalue = options.retrieve("k");
 | 
|---|
 | 371 |   values.debug = options.retrieve("d");
 | 
|---|
 | 372 |   values.limit = atoi(options.retrieve("l"));
 | 
|---|
 | 373 |   values.check = options.retrieve("c");
 | 
|---|
 | 374 |   values.simple_input = options.retrieve("i");
 | 
|---|
| [52aacc] | 375 |   values.executablename = argv[0];
 | 
|---|
| [ec4b04] | 376 | 
 | 
|---|
 | 377 | #ifdef HAVE_CHEMISTRY_CCA
 | 
|---|
 | 378 |   values.cca_load = options.retrieve("cca-load");
 | 
|---|
 | 379 |   values.cca_path = options.retrieve("cca-path");
 | 
|---|
 | 380 | #endif
 | 
|---|
 | 381 | }
 | 
|---|
 | 382 | 
 | 
|---|
| [36d8ab] | 383 | /** Sets object and generic input file names.
 | 
|---|
 | 384 |  *
 | 
|---|
 | 385 |  * \param object_input filename of object-oriented input
 | 
|---|
 | 386 |  * \param generic_input filename of generic input
 | 
|---|
| [ec4b04] | 387 |  * \param options (command-line)option structure
 | 
|---|
| [36d8ab] | 388 |  * \param argc argument count
 | 
|---|
 | 389 |  * \param argv argument array
 | 
|---|
 | 390 |  */
 | 
|---|
 | 391 | void getInputFileNames(
 | 
|---|
 | 392 |     const char *&object_input,
 | 
|---|
 | 393 |     const char *&generic_input,
 | 
|---|
 | 394 |     GetLongOpt &options,
 | 
|---|
| [2fbba84] | 395 |     int optind,
 | 
|---|
| [36d8ab] | 396 |     int argc,
 | 
|---|
 | 397 |     char **argv)
 | 
|---|
 | 398 | {
 | 
|---|
 | 399 |   // initialize keyval input
 | 
|---|
 | 400 |   object_input = options.retrieve("f");
 | 
|---|
 | 401 |   generic_input = 0;
 | 
|---|
 | 402 |   if (argc - optind == 0) {
 | 
|---|
 | 403 |     generic_input = 0;
 | 
|---|
 | 404 |   }
 | 
|---|
 | 405 |   else if (argc - optind == 1) {
 | 
|---|
 | 406 |     generic_input = argv[optind];
 | 
|---|
 | 407 |   }
 | 
|---|
| [2fbba84] | 408 |   else if (!options.retrieve("n")) {
 | 
|---|
| [36d8ab] | 409 |     options.usage();
 | 
|---|
 | 410 |     throw invalid_argument("extra arguments given");
 | 
|---|
 | 411 |   }
 | 
|---|
 | 412 | 
 | 
|---|
 | 413 |   if (object_input == 0 && generic_input == 0) {
 | 
|---|
 | 414 |     generic_input = "mpqc.in";
 | 
|---|
 | 415 |     }
 | 
|---|
| [2fbba84] | 416 |   else if (object_input && !options.retrieve("n") && generic_input) {
 | 
|---|
| [36d8ab] | 417 |     options.usage();
 | 
|---|
 | 418 |     throw invalid_argument("only one of -f and a file argument can be given");
 | 
|---|
 | 419 |     }
 | 
|---|
 | 420 | }
 | 
|---|
 | 421 | 
 | 
|---|
| [aa42a9] | 422 | /** Gets the MPI Message group.
 | 
|---|
 | 423 |  *
 | 
|---|
 | 424 |  * \param grp reference to obtained group
 | 
|---|
 | 425 |  * \param argc argument count
 | 
|---|
 | 426 |  * \param argv argument array
 | 
|---|
 | 427 |  */
 | 
|---|
| [36d8ab] | 428 | void getMessageGroup(
 | 
|---|
 | 429 |     Ref<MessageGrp> &grp,
 | 
|---|
 | 430 |     int argc,
 | 
|---|
 | 431 |     char **argv)
 | 
|---|
| [aa42a9] | 432 | {
 | 
|---|
 | 433 | #if defined(HAVE_MPI) && defined(ALWAYS_USE_MPI)
 | 
|---|
 | 434 |   grp = new MPIMessageGrp(&argc, &argv);
 | 
|---|
 | 435 | #endif
 | 
|---|
 | 436 |   if (grp.null()) grp = MessageGrp::initial_messagegrp(argc, argv);
 | 
|---|
 | 437 |   if (grp.nonnull())
 | 
|---|
 | 438 |     MessageGrp::set_default_messagegrp(grp);
 | 
|---|
 | 439 |   else
 | 
|---|
 | 440 |     grp = MessageGrp::get_default_messagegrp();
 | 
|---|
 | 441 | }
 | 
|---|
 | 442 | 
 | 
|---|
| [203fe4] | 443 | /** Sets the base name of output files.
 | 
|---|
 | 444 |  *
 | 
|---|
 | 445 |  * \param input input file name
 | 
|---|
 | 446 |  * \param output output file name
 | 
|---|
 | 447 |  */
 | 
|---|
 | 448 | void setOutputBaseName(const char *input, const char *output)
 | 
|---|
 | 449 | {
 | 
|---|
 | 450 |   const char *basename_source;
 | 
|---|
 | 451 |   if (output) basename_source = output;
 | 
|---|
 | 452 |   else        basename_source = input;
 | 
|---|
| [499cea] | 453 |   const char *baseprefix = ::strrchr(basename_source, '.');
 | 
|---|
 | 454 |   int nfilebase = 1;
 | 
|---|
 | 455 |   if (baseprefix == NULL) {
 | 
|---|
 | 456 |     std::cerr << "setOutputBaseName() - ERROR: basename_source "
 | 
|---|
 | 457 |         << basename_source << " contains no dot (.)." << std::endl;
 | 
|---|
 | 458 |     nfilebase = ::strlen(basename_source);
 | 
|---|
 | 459 |   } else
 | 
|---|
 | 460 |     nfilebase = (int) (baseprefix - basename_source);
 | 
|---|
| [203fe4] | 461 |   char *basename = new char[nfilebase + 1];
 | 
|---|
 | 462 |   strncpy(basename, basename_source, nfilebase);
 | 
|---|
 | 463 |   basename[nfilebase] = '\0';
 | 
|---|
 | 464 |   SCFormIO::set_default_basename(basename);
 | 
|---|
 | 465 |   delete[] basename;
 | 
|---|
 | 466 | }
 | 
|---|
 | 467 | 
 | 
|---|
| [d39b2b] | 468 | /** Prints current key values.
 | 
|---|
 | 469 |  *
 | 
|---|
 | 470 |  * \param keyval key value structure
 | 
|---|
 | 471 |  * \param opt optimization structure
 | 
|---|
 | 472 |  * \param molname name of molecule
 | 
|---|
| [a98b86] | 473 |  * \param restartfile name of restartfile
 | 
|---|
| [d39b2b] | 474 |  */
 | 
|---|
 | 475 | void printOptions(
 | 
|---|
 | 476 |     Ref<KeyVal> &keyval,
 | 
|---|
 | 477 |     Ref<Optimize> &opt,
 | 
|---|
 | 478 |     const char *molname,
 | 
|---|
 | 479 |     const char *restartfile)
 | 
|---|
 | 480 | {
 | 
|---|
 | 481 |   int restart = keyval->booleanvalue("restart",truevalue);
 | 
|---|
 | 482 | 
 | 
|---|
 | 483 |   int checkpoint = keyval->booleanvalue("checkpoint",truevalue);
 | 
|---|
 | 484 | 
 | 
|---|
 | 485 |   int savestate = keyval->booleanvalue("savestate",truevalue);
 | 
|---|
 | 486 | 
 | 
|---|
 | 487 |   int do_energy = keyval->booleanvalue("do_energy",truevalue);
 | 
|---|
 | 488 | 
 | 
|---|
 | 489 |   int do_grad = keyval->booleanvalue("do_gradient",falsevalue);
 | 
|---|
 | 490 | 
 | 
|---|
 | 491 |   int do_opt = keyval->booleanvalue("optimize",truevalue);
 | 
|---|
 | 492 | 
 | 
|---|
 | 493 |   int do_pdb = keyval->booleanvalue("write_pdb",falsevalue);
 | 
|---|
 | 494 | 
 | 
|---|
 | 495 |   int print_mole = keyval->booleanvalue("print_mole",truevalue);
 | 
|---|
 | 496 | 
 | 
|---|
 | 497 |   int print_timings = keyval->booleanvalue("print_timings",truevalue);
 | 
|---|
 | 498 | 
 | 
|---|
 | 499 |   // sanity checks for the benefit of reasonable looking output
 | 
|---|
 | 500 |   if (opt.null()) do_opt=0;
 | 
|---|
 | 501 | 
 | 
|---|
 | 502 |   ExEnv::out0() << endl << indent
 | 
|---|
 | 503 |        << "MPQC options:" << endl << incindent
 | 
|---|
 | 504 |        << indent << "matrixkit     = <"
 | 
|---|
 | 505 |        << SCMatrixKit::default_matrixkit()->class_name() << ">" << endl
 | 
|---|
 | 506 |        << indent << "filename      = " << molname << endl
 | 
|---|
 | 507 |        << indent << "restart_file  = " << restartfile << endl
 | 
|---|
 | 508 |        << indent << "restart       = " << (restart ? "yes" : "no") << endl
 | 
|---|
 | 509 |        << indent << "checkpoint    = " << (checkpoint ? "yes" : "no") << endl
 | 
|---|
 | 510 |        << indent << "savestate     = " << (savestate ? "yes" : "no") << endl
 | 
|---|
 | 511 |        << indent << "do_energy     = " << (do_energy ? "yes" : "no") << endl
 | 
|---|
 | 512 |        << indent << "do_gradient   = " << (do_grad ? "yes" : "no") << endl
 | 
|---|
 | 513 |        << indent << "optimize      = " << (do_opt ? "yes" : "no") << endl
 | 
|---|
 | 514 |        << indent << "write_pdb     = " << (do_pdb ? "yes" : "no") << endl
 | 
|---|
 | 515 |        << indent << "print_mole    = " << (print_mole ? "yes" : "no") << endl
 | 
|---|
 | 516 |        << indent << "print_timings = " << (print_timings ? "yes" : "no")
 | 
|---|
 | 517 |        << endl << decindent;
 | 
|---|
 | 518 | 
 | 
|---|
 | 519 | }
 | 
|---|
 | 520 | 
 | 
|---|
| [a98b86] | 521 | /** Saves the current state to checkpoint file.
 | 
|---|
 | 522 |  *
 | 
|---|
 | 523 |  * \param keyval key value structure
 | 
|---|
 | 524 |  * \param opt optimization structure
 | 
|---|
 | 525 |  * \param grp message group
 | 
|---|
 | 526 |  * \param mole MolecularEnergy object
 | 
|---|
 | 527 |  * \param molname name of molecule
 | 
|---|
 | 528 |  * \param ckptfile name of check point file
 | 
|---|
 | 529 |  */
 | 
|---|
 | 530 | void saveState(
 | 
|---|
 | 531 |     char *wfn_file,
 | 
|---|
 | 532 |     int savestate,
 | 
|---|
 | 533 |     Ref<Optimize> &opt,
 | 
|---|
 | 534 |     Ref<MessageGrp> &grp,
 | 
|---|
 | 535 |     Ref<MolecularEnergy> &mole,
 | 
|---|
 | 536 |     char *&molname,
 | 
|---|
 | 537 |     char *&ckptfile)
 | 
|---|
 | 538 | {
 | 
|---|
 | 539 |   // function stuff
 | 
|---|
 | 540 |   if (savestate) {
 | 
|---|
 | 541 |     if (opt.nonnull()) {
 | 
|---|
 | 542 |       if (grp->me() == 0) {
 | 
|---|
 | 543 |         ckptfile = new char[strlen(molname)+6];
 | 
|---|
 | 544 |         sprintf(ckptfile,"%s.ckpt",molname);
 | 
|---|
 | 545 |       }
 | 
|---|
 | 546 |       else {
 | 
|---|
 | 547 |         ckptfile = new char[strlen(devnull)+1];
 | 
|---|
 | 548 |         strcpy(ckptfile, devnull);
 | 
|---|
 | 549 |       }
 | 
|---|
 | 550 | 
 | 
|---|
 | 551 |       StateOutBin so(ckptfile);
 | 
|---|
 | 552 |       SavableState::save_state(opt.pointer(),so);
 | 
|---|
 | 553 |       so.close();
 | 
|---|
 | 554 | 
 | 
|---|
 | 555 |       delete[] ckptfile;
 | 
|---|
 | 556 |     }
 | 
|---|
 | 557 | 
 | 
|---|
 | 558 |     if (mole.nonnull()) {
 | 
|---|
 | 559 |       if (grp->me() == 0) {
 | 
|---|
 | 560 |         if (wfn_file == 0) {
 | 
|---|
 | 561 |           wfn_file = new char[strlen(molname)+6];
 | 
|---|
 | 562 |           sprintf(wfn_file,"%s.wfn",molname);
 | 
|---|
 | 563 |         }
 | 
|---|
 | 564 |       }
 | 
|---|
 | 565 |       else {
 | 
|---|
 | 566 |         delete[] wfn_file;
 | 
|---|
 | 567 |         wfn_file = new char[strlen(devnull)+1];
 | 
|---|
 | 568 |         strcpy(wfn_file, devnull);
 | 
|---|
 | 569 |       }
 | 
|---|
 | 570 | 
 | 
|---|
 | 571 |       StateOutBin so(wfn_file);
 | 
|---|
 | 572 |       SavableState::save_state(mole.pointer(),so);
 | 
|---|
 | 573 |       so.close();
 | 
|---|
 | 574 | 
 | 
|---|
 | 575 |     }
 | 
|---|
 | 576 |   }
 | 
|---|
 | 577 |   delete[] wfn_file;
 | 
|---|
 | 578 | }
 | 
|---|
 | 579 | 
 | 
|---|
| [8860a6] | 580 | /** Sets up indentation and output modes.
 | 
|---|
 | 581 |  *
 | 
|---|
 | 582 |  * \param grp message group
 | 
|---|
 | 583 |  */
 | 
|---|
 | 584 | void setupSCFormIO(
 | 
|---|
 | 585 |     Ref<MessageGrp> &grp
 | 
|---|
 | 586 |     )
 | 
|---|
 | 587 | {
 | 
|---|
 | 588 |   SCFormIO::setindent(ExEnv::outn(), 2);
 | 
|---|
 | 589 |   SCFormIO::setindent(ExEnv::errn(), 2);
 | 
|---|
 | 590 |   SCFormIO::setindent(cout, 2);
 | 
|---|
 | 591 |   SCFormIO::setindent(cerr, 2);
 | 
|---|
 | 592 | 
 | 
|---|
 | 593 |   SCFormIO::set_printnode(0);
 | 
|---|
 | 594 |   if (grp->n() > 1)
 | 
|---|
 | 595 |     SCFormIO::init_mp(grp->me());
 | 
|---|
 | 596 | }
 | 
|---|
 | 597 | 
 | 
|---|
| [c676ca] | 598 | /** Initialises the timer.
 | 
|---|
 | 599 |  *
 | 
|---|
 | 600 |  * \param grp message group
 | 
|---|
 | 601 |  * \param keyval key value structure
 | 
|---|
 | 602 |  * \param tim timing structure
 | 
|---|
 | 603 |  */
 | 
|---|
 | 604 | void initTimings(
 | 
|---|
 | 605 |     Ref<MessageGrp> &grp,
 | 
|---|
 | 606 |     Ref<KeyVal> &keyval,
 | 
|---|
 | 607 |     Ref<RegionTimer> &tim
 | 
|---|
 | 608 |     )
 | 
|---|
 | 609 | {
 | 
|---|
 | 610 |   grp->sync(); // make sure nodes are sync'ed before starting timings
 | 
|---|
 | 611 |   if (keyval->exists("timer")) tim << keyval->describedclassvalue("timer");
 | 
|---|
 | 612 |   else                         tim = new ParallelRegionTimer(grp,"mpqc",1,1);
 | 
|---|
 | 613 |   RegionTimer::set_default_regiontimer(tim);
 | 
|---|
 | 614 | 
 | 
|---|
 | 615 |   if (tim.nonnull()) tim->enter("input");
 | 
|---|
 | 616 | }
 | 
|---|
 | 617 | 
 | 
|---|
| [3d4397] | 618 | /** Prints the header of the output.
 | 
|---|
 | 619 |  *
 | 
|---|
 | 620 |  * \param tim timing structure
 | 
|---|
 | 621 |  */
 | 
|---|
 | 622 | void makeAnnouncement(
 | 
|---|
 | 623 |     Ref<RegionTimer> &tim
 | 
|---|
 | 624 |     )
 | 
|---|
 | 625 | {
 | 
|---|
 | 626 |   const char title1[] = "MPQC: Massively Parallel Quantum Chemistry";
 | 
|---|
 | 627 |   int ntitle1 = sizeof(title1);
 | 
|---|
 | 628 |   const char title2[] = "Version " SC_VERSION;
 | 
|---|
 | 629 |   int ntitle2 = sizeof(title2);
 | 
|---|
 | 630 |   ExEnv::out0() << endl;
 | 
|---|
 | 631 |   ExEnv::out0() << indent;
 | 
|---|
 | 632 |   for (int i=0; i<(80-ntitle1)/2; i++) ExEnv::out0() << ' ';
 | 
|---|
 | 633 |   ExEnv::out0() << title1 << endl;
 | 
|---|
 | 634 |   ExEnv::out0() << indent;
 | 
|---|
 | 635 |   for (int i=0; i<(80-ntitle2)/2; i++) ExEnv::out0() << ' ';
 | 
|---|
 | 636 |   ExEnv::out0() << title2 << endl << endl;
 | 
|---|
 | 637 | 
 | 
|---|
 | 638 |   const char *tstr = 0;
 | 
|---|
 | 639 | #if defined(HAVE_TIME) && defined(HAVE_CTIME)
 | 
|---|
 | 640 |   time_t t;
 | 
|---|
 | 641 |   time(&t);
 | 
|---|
 | 642 |   tstr = ctime(&t);
 | 
|---|
 | 643 | #endif
 | 
|---|
 | 644 |   if (!tstr) {
 | 
|---|
 | 645 |     tstr = "UNKNOWN";
 | 
|---|
 | 646 |   }
 | 
|---|
 | 647 | 
 | 
|---|
 | 648 |   ExEnv::out0()
 | 
|---|
 | 649 |        << indent << scprintf("Machine:    %s", TARGET_ARCH) << endl
 | 
|---|
 | 650 |        << indent << scprintf("User:       %s@%s",
 | 
|---|
 | 651 |                              ExEnv::username(), ExEnv::hostname()) << endl
 | 
|---|
 | 652 |        << indent << scprintf("Start Time: %s", tstr) << endl;
 | 
|---|
 | 653 | }
 | 
|---|
 | 654 | 
 | 
|---|
| [d2d7fc] | 655 | /** Parse the input configuration from char array into keyvalue container.
 | 
|---|
 | 656 |  *
 | 
|---|
 | 657 |  * \param parsedkv key value container to foll
 | 
|---|
 | 658 |  * \param values temporary options value structure
 | 
|---|
 | 659 |  * \param in_char_array char array with input file
 | 
|---|
 | 660 |  * \param use_simple_input whether the format in \a in_char_array is simple (1)
 | 
|---|
 | 661 |  *        or object-oriented (0)
 | 
|---|
 | 662 |  */
 | 
|---|
 | 663 | void parseIntoKeyValue(
 | 
|---|
 | 664 |     Ref<ParsedKeyVal> &parsedkv,
 | 
|---|
 | 665 |     struct OptionValues &values,
 | 
|---|
| [516fb4] | 666 |     char *&in_char_array,
 | 
|---|
| [d2d7fc] | 667 |     int use_simple_input)
 | 
|---|
 | 668 | {
 | 
|---|
 | 669 |   if (use_simple_input) {
 | 
|---|
 | 670 |     MPQCIn mpqcin;
 | 
|---|
 | 671 |     char *simple_input_text = mpqcin.parse_string(in_char_array);
 | 
|---|
 | 672 |     if (values.simple_input) {
 | 
|---|
 | 673 |       ExEnv::out0() << "Generated object-oriented input file:" << endl
 | 
|---|
 | 674 |                    << simple_input_text
 | 
|---|
 | 675 |                    << endl;
 | 
|---|
 | 676 |       exit(0);
 | 
|---|
 | 677 |     }
 | 
|---|
 | 678 |     parsedkv = new ParsedKeyVal();
 | 
|---|
 | 679 |     parsedkv->parse_string(simple_input_text);
 | 
|---|
 | 680 |     delete[] simple_input_text;
 | 
|---|
 | 681 |   } else {
 | 
|---|
 | 682 |     parsedkv = new ParsedKeyVal();
 | 
|---|
 | 683 |     parsedkv->parse_string(in_char_array);
 | 
|---|
 | 684 |   }
 | 
|---|
 | 685 | }
 | 
|---|
 | 686 | 
 | 
|---|
| [41f82c] | 687 | /** Parse the input file into the key value container.
 | 
|---|
 | 688 |  *
 | 
|---|
 | 689 |  * \param grp message group
 | 
|---|
| [3cb97b] | 690 |  * \param parsedkev keyvalue container on return
 | 
|---|
| [ec4b04] | 691 |  * \param values (command-line) options structure
 | 
|---|
| [41f82c] | 692 |  * \param input input file name
 | 
|---|
 | 693 |  * \param generic_input filename of generic input
 | 
|---|
| [d2d7fc] | 694 |  * \param in_char_array char array with input file's contents on return
 | 
|---|
 | 695 |  * \param use_simple_input whether the file contents is in simple format (1)
 | 
|---|
 | 696 |  *        or object-oriented (0)
 | 
|---|
| [41f82c] | 697 |  */
 | 
|---|
 | 698 | void parseInputfile(
 | 
|---|
 | 699 |     Ref<MessageGrp> &grp,
 | 
|---|
 | 700 |     Ref<ParsedKeyVal> &parsedkv,
 | 
|---|
| [ec4b04] | 701 |     struct OptionValues &values,
 | 
|---|
| [41f82c] | 702 |     const char *&input,
 | 
|---|
| [d2d7fc] | 703 |     const char *&generic_input,
 | 
|---|
 | 704 |     char *&in_char_array,
 | 
|---|
 | 705 |     int &use_simple_input
 | 
|---|
| [41f82c] | 706 |     )
 | 
|---|
 | 707 | {
 | 
|---|
 | 708 |   // read the input file on only node 0
 | 
|---|
 | 709 |   if (grp->me() == 0) {
 | 
|---|
 | 710 |     ifstream is(input);
 | 
|---|
 | 711 | #ifdef HAVE_SSTREAM
 | 
|---|
 | 712 |     ostringstream ostrs;
 | 
|---|
 | 713 |     is >> ostrs.rdbuf();
 | 
|---|
 | 714 |     int n = 1 + strlen(ostrs.str().c_str());
 | 
|---|
 | 715 |     in_char_array = strcpy(new char[n],ostrs.str().c_str());
 | 
|---|
 | 716 | #else
 | 
|---|
 | 717 |     ostrstream ostrs;
 | 
|---|
 | 718 |     is >> ostrs.rdbuf();
 | 
|---|
 | 719 |     ostrs << ends;
 | 
|---|
 | 720 |     in_char_array = ostrs.str();
 | 
|---|
 | 721 |     int n = ostrs.pcount();
 | 
|---|
 | 722 | #endif
 | 
|---|
 | 723 |     grp->bcast(n);
 | 
|---|
 | 724 |     grp->bcast(in_char_array, n);
 | 
|---|
 | 725 |     }
 | 
|---|
 | 726 |   else {
 | 
|---|
 | 727 |     int n;
 | 
|---|
 | 728 |     grp->bcast(n);
 | 
|---|
 | 729 |     in_char_array = new char[n];
 | 
|---|
 | 730 |     grp->bcast(in_char_array, n);
 | 
|---|
 | 731 |     }
 | 
|---|
 | 732 | 
 | 
|---|
 | 733 |   if (generic_input && grp->me() == 0) {
 | 
|---|
 | 734 |     MPQCIn mpqcin;
 | 
|---|
 | 735 |     use_simple_input = mpqcin.check_string(in_char_array);
 | 
|---|
 | 736 |   }
 | 
|---|
 | 737 |   else {
 | 
|---|
 | 738 |     use_simple_input = 0;
 | 
|---|
 | 739 |   }
 | 
|---|
 | 740 |   grp->bcast(use_simple_input);
 | 
|---|
 | 741 | }
 | 
|---|
 | 742 | 
 | 
|---|
| [3cb97b] | 743 | /** Get the thread group.
 | 
|---|
 | 744 |  *
 | 
|---|
 | 745 |  * \param keyval keyvalue container
 | 
|---|
 | 746 |  * \param thread thread group on return
 | 
|---|
 | 747 |  * \param argc argument count
 | 
|---|
 | 748 |  * \param argv argument array
 | 
|---|
 | 749 |  */
 | 
|---|
 | 750 | void getThreadGroup(
 | 
|---|
 | 751 |     Ref<KeyVal> &keyval,
 | 
|---|
 | 752 |     Ref<ThreadGrp> &thread,
 | 
|---|
 | 753 |     int argc,
 | 
|---|
 | 754 |     char **argv)
 | 
|---|
 | 755 | {
 | 
|---|
 | 756 |   //first try the commandline and environment
 | 
|---|
 | 757 |   thread = ThreadGrp::initial_threadgrp(argc, argv);
 | 
|---|
 | 758 | 
 | 
|---|
 | 759 |   // if we still don't have a group, try reading the thread group
 | 
|---|
 | 760 |   // from the input
 | 
|---|
 | 761 |   if (thread.null()) {
 | 
|---|
 | 762 |     thread << keyval->describedclassvalue("thread");
 | 
|---|
 | 763 |   }
 | 
|---|
 | 764 | 
 | 
|---|
 | 765 |   if (thread.nonnull())
 | 
|---|
 | 766 |     ThreadGrp::set_default_threadgrp(thread);
 | 
|---|
 | 767 |   else
 | 
|---|
 | 768 |     thread = ThreadGrp::get_default_threadgrp();
 | 
|---|
 | 769 | }
 | 
|---|
 | 770 | 
 | 
|---|
| [7ed4e8] | 771 | /** Get the memory group.
 | 
|---|
 | 772 |  *
 | 
|---|
 | 773 |  * \param keyval keyvalue container
 | 
|---|
 | 774 |  * \param memory memory group on return
 | 
|---|
 | 775 |  * \param argc argument count
 | 
|---|
 | 776 |  * \param argv argument array
 | 
|---|
 | 777 |  */
 | 
|---|
 | 778 | void getMemoryGroup(
 | 
|---|
 | 779 |     Ref<KeyVal> &keyval,
 | 
|---|
 | 780 |     Ref<MemoryGrp> &memory,
 | 
|---|
 | 781 |     int argc,
 | 
|---|
 | 782 |     char **argv)
 | 
|---|
 | 783 | {
 | 
|---|
 | 784 |   // first try the commandline and environment
 | 
|---|
 | 785 |   memory = MemoryGrp::initial_memorygrp(argc, argv);
 | 
|---|
 | 786 | 
 | 
|---|
 | 787 |   // if we still don't have a group, try reading the memory group
 | 
|---|
 | 788 |   // from the input
 | 
|---|
 | 789 |   if (memory.null()) {
 | 
|---|
 | 790 |     memory << keyval->describedclassvalue("memory");
 | 
|---|
 | 791 |   }
 | 
|---|
 | 792 | 
 | 
|---|
 | 793 |   if (memory.nonnull())
 | 
|---|
 | 794 |     MemoryGrp::set_default_memorygrp(memory);
 | 
|---|
 | 795 |   else
 | 
|---|
 | 796 |     memory = MemoryGrp::get_default_memorygrp();
 | 
|---|
 | 797 | }
 | 
|---|
 | 798 | 
 | 
|---|
| [09bc09] | 799 | /** Prepares CCA component if available.
 | 
|---|
 | 800 |  *
 | 
|---|
 | 801 |  * \param keyval keyvalue container
 | 
|---|
| [ec4b04] | 802 |  * \param values parsed (command-line) options
 | 
|---|
| [09bc09] | 803 |  */
 | 
|---|
 | 804 | void prepareCCA(
 | 
|---|
 | 805 |     Ref<KeyVal> &keyval,
 | 
|---|
| [ec4b04] | 806 |     struct OptionValues &values
 | 
|---|
| [09bc09] | 807 |     )
 | 
|---|
 | 808 | {
 | 
|---|
 | 809 | #ifdef HAVE_CHEMISTRY_CCA
 | 
|---|
 | 810 |   // initialize cca framework
 | 
|---|
 | 811 |   KeyValValuestring emptystring("");
 | 
|---|
 | 812 |   bool do_cca = keyval->booleanvalue("do_cca",falsevalue);
 | 
|---|
 | 813 | 
 | 
|---|
| [ec4b04] | 814 |   string cca_path(values.cca_path);
 | 
|---|
 | 815 |   string cca_load(values.cca_load);
 | 
|---|
| [09bc09] | 816 |   if(cca_path.size()==0)
 | 
|---|
 | 817 |     cca_path = keyval->stringvalue("cca_path",emptystring);
 | 
|---|
 | 818 |   if(cca_load.size()==0)
 | 
|---|
 | 819 |     cca_load = keyval->stringvalue("cca_load",emptystring);
 | 
|---|
 | 820 | 
 | 
|---|
 | 821 |   if( !do_cca && (cca_load.size() > 0 || cca_path.size() > 0) )
 | 
|---|
 | 822 |     do_cca = true;
 | 
|---|
 | 823 | 
 | 
|---|
 | 824 |   if(cca_path.size()==0) {
 | 
|---|
 | 825 |     #ifdef CCA_PATH
 | 
|---|
 | 826 |       cca_path = CCA_PATH;
 | 
|---|
 | 827 |     #endif
 | 
|---|
 | 828 |   }
 | 
|---|
 | 829 |   if(cca_load.size()==0) {
 | 
|---|
 | 830 |     cca_load += "MPQC.IntegralEvaluatorFactory";
 | 
|---|
 | 831 |   }
 | 
|---|
 | 832 | 
 | 
|---|
 | 833 |   if( cca_load.size() > 0 && cca_path.size() > 0 && do_cca ) {
 | 
|---|
 | 834 |     string cca_args = "--path " + cca_path + " --load " + cca_load;
 | 
|---|
 | 835 |     ExEnv::out0() << endl << indent << "Initializing CCA framework with args: "
 | 
|---|
 | 836 |                   << endl << indent << cca_args << endl;
 | 
|---|
 | 837 |     CCAEnv::init( cca_args );
 | 
|---|
 | 838 |   }
 | 
|---|
 | 839 | #endif
 | 
|---|
 | 840 | }
 | 
|---|
 | 841 | 
 | 
|---|
| [f5403d] | 842 | /** Setup debugger.
 | 
|---|
 | 843 |  *
 | 
|---|
 | 844 |  * \param keyval keyvalue container
 | 
|---|
 | 845 |  * \param grp message group
 | 
|---|
 | 846 |  * \param debugger debugger structure
 | 
|---|
 | 847 |  * \param options parsed command line options
 | 
|---|
 | 848 |  */
 | 
|---|
 | 849 | void setupDebugger(
 | 
|---|
 | 850 |     Ref<KeyVal> &keyval,
 | 
|---|
 | 851 |     Ref<MessageGrp> &grp,
 | 
|---|
 | 852 |     Ref<Debugger> &debugger,
 | 
|---|
| [52aacc] | 853 |     struct OptionValues &values)
 | 
|---|
| [f5403d] | 854 | {
 | 
|---|
 | 855 |   debugger << keyval->describedclassvalue("debug");
 | 
|---|
 | 856 |   if (debugger.nonnull()) {
 | 
|---|
 | 857 |     Debugger::set_default_debugger(debugger);
 | 
|---|
| [52aacc] | 858 |     debugger->set_exec(values.executablename.c_str());
 | 
|---|
| [f5403d] | 859 |     debugger->set_prefix(grp->me());
 | 
|---|
| [ec4b04] | 860 |     if (values.debug)
 | 
|---|
| [f5403d] | 861 |       debugger->debug("Starting debugger because -d given on command line.");
 | 
|---|
 | 862 |   }
 | 
|---|
 | 863 | }
 | 
|---|
 | 864 | 
 | 
|---|
| [09bc09] | 865 | /** Get integral factory.
 | 
|---|
 | 866 |  *
 | 
|---|
 | 867 |  * \param keyval keyvalue container
 | 
|---|
 | 868 |  * \param integral integral group on return
 | 
|---|
 | 869 |  * \param argc argument count
 | 
|---|
 | 870 |  * \param argv argument array
 | 
|---|
 | 871 |  */
 | 
|---|
 | 872 | void getIntegralFactory(
 | 
|---|
 | 873 |     Ref<KeyVal> &keyval,
 | 
|---|
 | 874 |     Ref<Integral> &integral,
 | 
|---|
 | 875 |     int argc,
 | 
|---|
 | 876 |     char **argv)
 | 
|---|
 | 877 | {
 | 
|---|
 | 878 |   // first try commandline and environment
 | 
|---|
 | 879 |   integral = Integral::initial_integral(argc, argv);
 | 
|---|
 | 880 | 
 | 
|---|
 | 881 |   // if we still don't have a integral, try reading the integral
 | 
|---|
 | 882 |   // from the input
 | 
|---|
 | 883 |   if (integral.null()) {
 | 
|---|
 | 884 |     integral << keyval->describedclassvalue("integrals");
 | 
|---|
 | 885 |   }
 | 
|---|
 | 886 | 
 | 
|---|
 | 887 |   if (integral.nonnull())
 | 
|---|
 | 888 |     Integral::set_default_integral(integral);
 | 
|---|
 | 889 |   else
 | 
|---|
 | 890 |     integral = Integral::get_default_integral();
 | 
|---|
 | 891 | 
 | 
|---|
 | 892 | }
 | 
|---|
 | 893 | 
 | 
|---|
| [666f70] | 894 | void performRestart(
 | 
|---|
 | 895 |     Ref<KeyVal> &keyval,
 | 
|---|
 | 896 |     Ref<MessageGrp> &grp,
 | 
|---|
 | 897 |     Ref<Optimize> &opt,
 | 
|---|
 | 898 |     Ref<MolecularEnergy> &mole,
 | 
|---|
 | 899 |     char *&restartfile
 | 
|---|
 | 900 |     )
 | 
|---|
 | 901 | {
 | 
|---|
 | 902 |   int restart = keyval->booleanvalue("restart",truevalue);
 | 
|---|
 | 903 |   struct stat sb;
 | 
|---|
 | 904 |   int statresult, statsize;
 | 
|---|
 | 905 |   if (restart) {
 | 
|---|
 | 906 |     if (grp->me() == 0) {
 | 
|---|
 | 907 |       statresult = stat(restartfile,&sb);
 | 
|---|
 | 908 |       statsize = (statresult==0) ? sb.st_size : 0;
 | 
|---|
 | 909 |     }
 | 
|---|
 | 910 |     grp->bcast(statresult);
 | 
|---|
 | 911 |     grp->bcast(statsize);
 | 
|---|
 | 912 |   }
 | 
|---|
 | 913 |   if (restart && statresult==0 && statsize) {
 | 
|---|
 | 914 |     BcastStateInBin si(grp,restartfile);
 | 
|---|
 | 915 |     if (keyval->exists("override")) {
 | 
|---|
 | 916 |       si.set_override(new PrefixKeyVal(keyval,"override"));
 | 
|---|
 | 917 |     }
 | 
|---|
 | 918 |     char *suf = strrchr(restartfile,'.');
 | 
|---|
 | 919 |     if (!strcmp(suf,".wfn")) {
 | 
|---|
 | 920 |       mole << SavableState::key_restore_state(si,"mole");
 | 
|---|
 | 921 |       ExEnv::out0() << endl
 | 
|---|
 | 922 |                    << indent << "Restored <" << mole->class_name()
 | 
|---|
 | 923 |                    << "> from " << restartfile << endl;
 | 
|---|
 | 924 | 
 | 
|---|
 | 925 |       opt << keyval->describedclassvalue("opt");
 | 
|---|
 | 926 |       if (opt.nonnull())
 | 
|---|
 | 927 |         opt->set_function(mole.pointer());
 | 
|---|
 | 928 |     }
 | 
|---|
 | 929 |     else {
 | 
|---|
 | 930 |       opt << SavableState::key_restore_state(si,"opt");
 | 
|---|
 | 931 |       if (opt.nonnull()) {
 | 
|---|
 | 932 |         mole << opt->function();
 | 
|---|
 | 933 |         ExEnv::out0() << endl << indent
 | 
|---|
 | 934 |              << "Restored <Optimize> from " << restartfile << endl;
 | 
|---|
 | 935 |       }
 | 
|---|
 | 936 |     }
 | 
|---|
 | 937 |   } else {
 | 
|---|
 | 938 |     mole << keyval->describedclassvalue("mole");
 | 
|---|
 | 939 |     opt << keyval->describedclassvalue("opt");
 | 
|---|
 | 940 |   }
 | 
|---|
 | 941 | }
 | 
|---|
 | 942 | 
 | 
|---|
| [9b827f] | 943 | char *setMolecularCheckpointFile(
 | 
|---|
 | 944 |     Ref<KeyVal> &keyval,
 | 
|---|
 | 945 |     Ref<MessageGrp> &grp,
 | 
|---|
 | 946 |     Ref<MolecularEnergy> &mole,
 | 
|---|
 | 947 |     char *mole_ckpt_file
 | 
|---|
 | 948 |     )
 | 
|---|
 | 949 | {
 | 
|---|
 | 950 |   int checkpoint = keyval->booleanvalue("checkpoint",truevalue);
 | 
|---|
 | 951 |   int checkpoint_freq = keyval->intvalue("checkpoint_freq",KeyValValueint(1));
 | 
|---|
 | 952 |   if (mole.nonnull()) {
 | 
|---|
 | 953 |     MolecularFormula mf(mole->molecule());
 | 
|---|
 | 954 |     ExEnv::out0() << endl << indent
 | 
|---|
 | 955 |          << "Molecular formula " << mf.formula() << endl;
 | 
|---|
 | 956 |     if (checkpoint) {
 | 
|---|
 | 957 |       mole->set_checkpoint();
 | 
|---|
 | 958 |       if (grp->me() == 0) mole->set_checkpoint_file(mole_ckpt_file);
 | 
|---|
 | 959 |       else mole->set_checkpoint_file(devnull);
 | 
|---|
 | 960 |       mole->set_checkpoint_freq(checkpoint_freq);
 | 
|---|
 | 961 |     }
 | 
|---|
 | 962 |   }
 | 
|---|
 | 963 | }
 | 
|---|
| [666f70] | 964 | 
 | 
|---|
| [05c6bc] | 965 | /** Checks whether limit on command-line exceeds the basis functions.
 | 
|---|
 | 966 |  *
 | 
|---|
 | 967 |  * \param mole molecular energy object
 | 
|---|
| [ec4b04] | 968 |  * \param values temporarily storage for (command-line) options
 | 
|---|
| [05c6bc] | 969 |  * \return 0 - not exceeded, 1 - exceeded
 | 
|---|
 | 970 |  */
 | 
|---|
 | 971 | int checkBasisSetLimit(
 | 
|---|
| [ec4b04] | 972 |     Ref<MolecularEnergy> &mole,
 | 
|---|
 | 973 |     struct OptionValues &values
 | 
|---|
| [05c6bc] | 974 |     )
 | 
|---|
 | 975 | {
 | 
|---|
| [ec4b04] | 976 |   int check = (values.check != (const char *)0);
 | 
|---|
 | 977 |   int limit = values.limit;
 | 
|---|
| [05c6bc] | 978 |   if (limit) {
 | 
|---|
 | 979 |     Ref<Wavefunction> wfn; wfn << mole;
 | 
|---|
 | 980 |     if (wfn.nonnull() && wfn->ao_dimension()->n() > limit) {
 | 
|---|
 | 981 |       ExEnv::out0() << endl << indent
 | 
|---|
 | 982 |            << "The limit of " << limit << " basis functions has been exceeded."
 | 
|---|
 | 983 |            << endl;
 | 
|---|
 | 984 |       check = 1;
 | 
|---|
 | 985 |     }
 | 
|---|
 | 986 |   }
 | 
|---|
 | 987 |   return check;
 | 
|---|
 | 988 | }
 | 
|---|
 | 989 | 
 | 
|---|
| [ad2befa] | 990 | /** Performs the energy optimization.
 | 
|---|
 | 991 |  *
 | 
|---|
 | 992 |  * \param opt optimization object
 | 
|---|
 | 993 |  * \param mole molecular energy object
 | 
|---|
 | 994 |  * \return 0 - not read for frequency calculation, 1 - ready
 | 
|---|
 | 995 |  */
 | 
|---|
 | 996 | int performEnergyOptimization(
 | 
|---|
 | 997 |     Ref<Optimize> &opt,
 | 
|---|
 | 998 |     Ref<MolecularEnergy> &mole
 | 
|---|
 | 999 |     )
 | 
|---|
 | 1000 | {
 | 
|---|
 | 1001 |   int ready_for_freq = 0;
 | 
|---|
 | 1002 |   int result = opt->optimize();
 | 
|---|
 | 1003 |   if (result) {
 | 
|---|
 | 1004 |     ExEnv::out0() << indent
 | 
|---|
 | 1005 |          << "The optimization has converged." << endl << endl;
 | 
|---|
 | 1006 |     ExEnv::out0() << indent
 | 
|---|
 | 1007 |          << scprintf("Value of the MolecularEnergy: %15.10f",
 | 
|---|
 | 1008 |                      mole->energy())
 | 
|---|
 | 1009 |          << endl << endl;
 | 
|---|
 | 1010 |     ready_for_freq = 1;
 | 
|---|
 | 1011 |   } else {
 | 
|---|
 | 1012 |     ExEnv::out0() << indent
 | 
|---|
 | 1013 |          << "The optimization has NOT converged." << endl << endl;
 | 
|---|
 | 1014 |     ready_for_freq = 0;
 | 
|---|
 | 1015 |   }
 | 
|---|
 | 1016 |   return ready_for_freq;
 | 
|---|
 | 1017 | }
 | 
|---|
 | 1018 | 
 | 
|---|
| [d392067] | 1019 | /** Performs gradient calculation.
 | 
|---|
 | 1020 |  *
 | 
|---|
 | 1021 |  * \param mole molecular energy object
 | 
|---|
 | 1022 |  */
 | 
|---|
 | 1023 | void performGradientCalculation(
 | 
|---|
 | 1024 |     Ref<MolecularEnergy> &mole
 | 
|---|
 | 1025 |     )
 | 
|---|
 | 1026 | {
 | 
|---|
 | 1027 |   mole->do_gradient(1);
 | 
|---|
 | 1028 |   ExEnv::out0() << endl << indent
 | 
|---|
 | 1029 |        << scprintf("Value of the MolecularEnergy: %15.10f",
 | 
|---|
 | 1030 |                    mole->energy())
 | 
|---|
 | 1031 |        << endl;
 | 
|---|
 | 1032 |   if (mole->value_result().actual_accuracy()
 | 
|---|
 | 1033 |       > mole->value_result().desired_accuracy()) {
 | 
|---|
 | 1034 |     ExEnv::out0() << indent
 | 
|---|
 | 1035 |          << "WARNING: desired accuracy not achieved in energy" << endl;
 | 
|---|
 | 1036 |   }
 | 
|---|
 | 1037 |   ExEnv::out0() << endl;
 | 
|---|
 | 1038 |   // Use result_noupdate since the energy might not have converged
 | 
|---|
 | 1039 |   // to the desired accuracy in which case grabbing the result will
 | 
|---|
 | 1040 |   // start up the calculation again.  However the gradient might
 | 
|---|
 | 1041 |   // not have been computed (if we are restarting and the gradient
 | 
|---|
 | 1042 |   // isn't in the save file for example).
 | 
|---|
 | 1043 |   RefSCVector grad;
 | 
|---|
 | 1044 |   if (mole->gradient_result().computed()) {
 | 
|---|
 | 1045 |     grad = mole->gradient_result().result_noupdate();
 | 
|---|
 | 1046 |   }
 | 
|---|
 | 1047 |   else {
 | 
|---|
 | 1048 |     grad = mole->gradient();
 | 
|---|
 | 1049 |   }
 | 
|---|
 | 1050 |   if (grad.nonnull()) {
 | 
|---|
 | 1051 |     grad.print("Gradient of the MolecularEnergy:");
 | 
|---|
 | 1052 |     if (mole->gradient_result().actual_accuracy()
 | 
|---|
 | 1053 |         > mole->gradient_result().desired_accuracy()) {
 | 
|---|
 | 1054 |       ExEnv::out0() << indent
 | 
|---|
 | 1055 |            << "WARNING: desired accuracy not achieved in gradient" << endl;
 | 
|---|
 | 1056 |     }
 | 
|---|
 | 1057 |   }
 | 
|---|
 | 1058 | }
 | 
|---|
 | 1059 | 
 | 
|---|
| [bab0b1] | 1060 | /** Performs frequency calculation.
 | 
|---|
 | 1061 |  *
 | 
|---|
 | 1062 |  * \param mole molecular energy object
 | 
|---|
 | 1063 |  * \param molhess molecular hessian object
 | 
|---|
 | 1064 |  * \param molfreq molecular frequency object
 | 
|---|
 | 1065 |  */
 | 
|---|
 | 1066 | void performFrequencyCalculation(
 | 
|---|
 | 1067 |     Ref<MolecularEnergy> &mole,
 | 
|---|
 | 1068 |     Ref<MolecularHessian> &molhess,
 | 
|---|
 | 1069 |     Ref<MolecularFrequencies> &molfreq
 | 
|---|
 | 1070 | 
 | 
|---|
 | 1071 |     )
 | 
|---|
 | 1072 | {
 | 
|---|
 | 1073 |   RefSymmSCMatrix xhessian;
 | 
|---|
 | 1074 |   if (molhess.nonnull()) {
 | 
|---|
 | 1075 |     // if "hess" input was given, use it to compute the hessian
 | 
|---|
 | 1076 |     xhessian = molhess->cartesian_hessian();
 | 
|---|
 | 1077 |   }
 | 
|---|
 | 1078 |   else if (mole->hessian_implemented()) {
 | 
|---|
 | 1079 |     // if mole can compute the hessian, use that hessian
 | 
|---|
 | 1080 |     xhessian = mole->get_cartesian_hessian();
 | 
|---|
 | 1081 |   }
 | 
|---|
 | 1082 |   else if (mole->gradient_implemented()) {
 | 
|---|
 | 1083 |     // if mole can compute gradients, use gradients at finite
 | 
|---|
 | 1084 |     // displacements to compute the hessian
 | 
|---|
 | 1085 |     molhess = new FinDispMolecularHessian(mole);
 | 
|---|
 | 1086 |     xhessian = molhess->cartesian_hessian();
 | 
|---|
 | 1087 |   }
 | 
|---|
 | 1088 |   else {
 | 
|---|
 | 1089 |     ExEnv::out0() << "mpqc: WARNING: Frequencies cannot be computed" << endl;
 | 
|---|
 | 1090 |   }
 | 
|---|
 | 1091 | 
 | 
|---|
 | 1092 |   if (xhessian.nonnull()) {
 | 
|---|
 | 1093 |     char *hessfile = SCFormIO::fileext_to_filename(".hess");
 | 
|---|
 | 1094 |     MolecularHessian::write_cartesian_hessian(hessfile,
 | 
|---|
 | 1095 |                                               mole->molecule(), xhessian);
 | 
|---|
 | 1096 |     delete[] hessfile;
 | 
|---|
 | 1097 | 
 | 
|---|
 | 1098 |     molfreq->compute_frequencies(xhessian);
 | 
|---|
 | 1099 |     // DEGENERACY IS NOT CORRECT FOR NON-SINGLET CASES:
 | 
|---|
 | 1100 |     molfreq->thermochemistry(1);
 | 
|---|
 | 1101 |   }
 | 
|---|
 | 1102 | }
 | 
|---|
 | 1103 | 
 | 
|---|
| [5ef341] | 1104 | /** Renders some objects.
 | 
|---|
 | 1105 |  *
 | 
|---|
 | 1106 |  * \param renderer renderer object
 | 
|---|
 | 1107 |  * \param keyval keyvalue container
 | 
|---|
 | 1108 |  * \param tim timing object
 | 
|---|
 | 1109 |  * \param grp message group
 | 
|---|
 | 1110 |  */
 | 
|---|
 | 1111 | void renderObjects(
 | 
|---|
 | 1112 |     Ref<Render> &renderer,
 | 
|---|
 | 1113 |     Ref<KeyVal> &keyval,
 | 
|---|
 | 1114 |     Ref<RegionTimer> &tim,
 | 
|---|
 | 1115 |     Ref<MessageGrp> &grp
 | 
|---|
 | 1116 |     )
 | 
|---|
 | 1117 | {
 | 
|---|
 | 1118 |   Ref<RenderedObject> rendered;
 | 
|---|
 | 1119 |   rendered << keyval->describedclassvalue("rendered");
 | 
|---|
 | 1120 |   Ref<AnimatedObject> animated;
 | 
|---|
 | 1121 |   animated << keyval->describedclassvalue("rendered");
 | 
|---|
 | 1122 |   if (rendered.nonnull()) {
 | 
|---|
 | 1123 |     if (tim.nonnull()) tim->enter("render");
 | 
|---|
 | 1124 |     if (grp->me() == 0) renderer->render(rendered);
 | 
|---|
 | 1125 |     if (tim.nonnull()) tim->exit("render");
 | 
|---|
 | 1126 |   }
 | 
|---|
 | 1127 |   else if (animated.nonnull()) {
 | 
|---|
 | 1128 |     if (tim.nonnull()) tim->enter("render");
 | 
|---|
 | 1129 |     if (grp->me() == 0) renderer->animate(animated);
 | 
|---|
 | 1130 |     if (tim.nonnull()) tim->exit("render");
 | 
|---|
 | 1131 |   }
 | 
|---|
 | 1132 |   else {
 | 
|---|
 | 1133 |     if (tim.nonnull()) tim->enter("render");
 | 
|---|
 | 1134 |     int n = keyval->count("rendered");
 | 
|---|
 | 1135 |     for (int i=0; i<n; i++) {
 | 
|---|
 | 1136 |       rendered << keyval->describedclassvalue("rendered",i);
 | 
|---|
 | 1137 |       animated << keyval->describedclassvalue("rendered",i);
 | 
|---|
 | 1138 |       if (rendered.nonnull()) {
 | 
|---|
 | 1139 |         // make sure the object has a name so we don't overwrite its file
 | 
|---|
 | 1140 |         if (rendered->name() == 0) {
 | 
|---|
 | 1141 |           char ic[64];
 | 
|---|
 | 1142 |           sprintf(ic,"%02d",i);
 | 
|---|
 | 1143 |           rendered->set_name(ic);
 | 
|---|
 | 1144 |         }
 | 
|---|
 | 1145 |         if (grp->me() == 0) renderer->render(rendered);
 | 
|---|
 | 1146 |       }
 | 
|---|
 | 1147 |       else if (animated.nonnull()) {
 | 
|---|
 | 1148 |         // make sure the object has a name so we don't overwrite its file
 | 
|---|
 | 1149 |         if (animated->name() == 0) {
 | 
|---|
 | 1150 |           char ic[64];
 | 
|---|
 | 1151 |           sprintf(ic,"%02d",i);
 | 
|---|
 | 1152 |           animated->set_name(ic);
 | 
|---|
 | 1153 |         }
 | 
|---|
 | 1154 |         if (grp->me() == 0) renderer->animate(animated);
 | 
|---|
 | 1155 |       }
 | 
|---|
 | 1156 |     }
 | 
|---|
 | 1157 |     if (tim.nonnull()) tim->exit("render");
 | 
|---|
 | 1158 |   }
 | 
|---|
 | 1159 | }
 | 
|---|
 | 1160 | 
 | 
|---|
| [e9a571] | 1161 | /** Save the molecule to PDB file.
 | 
|---|
 | 1162 |  *
 | 
|---|
 | 1163 |  * \param do_pdb whether to save as pdb (1) or not (0)
 | 
|---|
 | 1164 |  * \param grp message group
 | 
|---|
 | 1165 |  * \param mole molecular energy object
 | 
|---|
 | 1166 |  * \param molname name of output file
 | 
|---|
 | 1167 |  */
 | 
|---|
 | 1168 | void saveToPdb(
 | 
|---|
 | 1169 |     int do_pdb,
 | 
|---|
 | 1170 |     Ref<MessageGrp> &grp,
 | 
|---|
 | 1171 |     Ref<MolecularEnergy> &mole,
 | 
|---|
 | 1172 |     const char *molname
 | 
|---|
 | 1173 |     )
 | 
|---|
 | 1174 | {
 | 
|---|
 | 1175 |   if (do_pdb && grp->me() == 0) {
 | 
|---|
 | 1176 |     char *ckptfile = new char[strlen(molname)+5];
 | 
|---|
 | 1177 |     sprintf(ckptfile, "%s.pdb", molname);
 | 
|---|
 | 1178 |     ofstream pdbfile(ckptfile);
 | 
|---|
 | 1179 |     mole->molecule()->print_pdb(pdbfile);
 | 
|---|
 | 1180 |     delete[] ckptfile;
 | 
|---|
 | 1181 |   }
 | 
|---|
 | 1182 | }
 | 
|---|
 | 1183 | 
 | 
|---|
| [ab755a] | 1184 | void init()
 | 
|---|
| [62dabe] | 1185 | {
 | 
|---|
 | 1186 |   //trash_stack();
 | 
|---|
 | 1187 | 
 | 
|---|
 | 1188 |   int i;
 | 
|---|
 | 1189 |   atexit(clean_up);
 | 
|---|
 | 1190 | 
 | 
|---|
 | 1191 | #ifdef HAVE_FEENABLEEXCEPT
 | 
|---|
 | 1192 |   // this uses a glibc extension to trap on individual exceptions
 | 
|---|
 | 1193 | # ifdef FE_DIVBYZERO
 | 
|---|
 | 1194 |   feenableexcept(FE_DIVBYZERO);
 | 
|---|
 | 1195 | # endif
 | 
|---|
 | 1196 | # ifdef FE_INVALID
 | 
|---|
 | 1197 |   feenableexcept(FE_INVALID);
 | 
|---|
 | 1198 | # endif
 | 
|---|
 | 1199 | # ifdef FE_OVERFLOW
 | 
|---|
 | 1200 |   feenableexcept(FE_OVERFLOW);
 | 
|---|
 | 1201 | # endif
 | 
|---|
 | 1202 | #endif
 | 
|---|
 | 1203 | 
 | 
|---|
 | 1204 | #ifdef HAVE_FEDISABLEEXCEPT
 | 
|---|
 | 1205 |   // this uses a glibc extension to not trap on individual exceptions
 | 
|---|
 | 1206 | # ifdef FE_UNDERFLOW
 | 
|---|
 | 1207 |   fedisableexcept(FE_UNDERFLOW);
 | 
|---|
 | 1208 | # endif
 | 
|---|
 | 1209 | # ifdef FE_INEXACT
 | 
|---|
 | 1210 |   fedisableexcept(FE_INEXACT);
 | 
|---|
 | 1211 | # endif
 | 
|---|
 | 1212 | #endif
 | 
|---|
 | 1213 | 
 | 
|---|
 | 1214 | #if defined(HAVE_SETRLIMIT)
 | 
|---|
 | 1215 |   struct rlimit rlim;
 | 
|---|
 | 1216 |   rlim.rlim_cur = 0;
 | 
|---|
 | 1217 |   rlim.rlim_max = 0;
 | 
|---|
 | 1218 |   setrlimit(RLIMIT_CORE,&rlim);
 | 
|---|
 | 1219 | #endif
 | 
|---|
| [ce1e39] | 1220 | }
 | 
|---|
 | 1221 | 
 | 
|---|
| [f137f7] | 1222 | /** Finds the region index to a given timer region name.
 | 
|---|
 | 1223 |  *
 | 
|---|
 | 1224 |  * @param nregion number of regions
 | 
|---|
 | 1225 |  * @param region_names array with name of each region
 | 
|---|
 | 1226 |  * @param name name of desired region
 | 
|---|
 | 1227 |  * @return index of desired region in array
 | 
|---|
 | 1228 |  */
 | 
|---|
 | 1229 | int findTimerRegion(const int &nregion, const char **®ion_names, const char *name)
 | 
|---|
 | 1230 | {
 | 
|---|
 | 1231 |   size_t region=0;
 | 
|---|
 | 1232 |   for (;region<nregion;++region) {
 | 
|---|
 | 1233 |     //std::cout << "Comparing " << region_names[region] << " and " << name << "." << std::endl;
 | 
|---|
 | 1234 |     if (strcmp(region_names[region], name) == 0)
 | 
|---|
 | 1235 |       break;
 | 
|---|
 | 1236 |   }
 | 
|---|
 | 1237 |   if (region == nregion)
 | 
|---|
 | 1238 |     region = 0;
 | 
|---|
 | 1239 |   return region;
 | 
|---|
 | 1240 | }
 | 
|---|
 | 1241 | 
 | 
|---|
| [035791] | 1242 | /** Performs the main work to calculate the ground state energies, gradients, etc.
 | 
|---|
 | 1243 |  *
 | 
|---|
| [4aba27] | 1244 |  * @param grp message group
 | 
|---|
| [035791] | 1245 |  * @param values temporary value storage for parsed command-line
 | 
|---|
 | 1246 |  * @param input input file name
 | 
|---|
 | 1247 |  * @param generic_input generic input file name
 | 
|---|
 | 1248 |  * @param in_char_array either NULL or contains char array with read input
 | 
|---|
 | 1249 |  * @param argc argument count
 | 
|---|
 | 1250 |  * @param argv argument array
 | 
|---|
 | 1251 |  */
 | 
|---|
| [c96b1d] | 1252 | void mainFunction(
 | 
|---|
| [4aba27] | 1253 |     Ref<MessageGrp> grp,
 | 
|---|
| [c96b1d] | 1254 |     struct OptionValues &values,
 | 
|---|
| [4aba27] | 1255 |     const char *&output,
 | 
|---|
| [c96b1d] | 1256 |     const char *&input,
 | 
|---|
 | 1257 |     const char *&generic_input,
 | 
|---|
| [516fb4] | 1258 |     char *&in_char_array,
 | 
|---|
| [c96b1d] | 1259 |     int argc,
 | 
|---|
| [850bce] | 1260 |     char **argv
 | 
|---|
 | 1261 | #ifdef HAVE_MPQCDATA
 | 
|---|
 | 1262 |     , MPQCData &data
 | 
|---|
 | 1263 | #endif
 | 
|---|
 | 1264 |     )
 | 
|---|
| [ce1e39] | 1265 | {
 | 
|---|
| [4aba27] | 1266 |   // get the basename for output files
 | 
|---|
 | 1267 |   setOutputBaseName(input, output);
 | 
|---|
| [ce1e39] | 1268 | 
 | 
|---|
| [41f82c] | 1269 |   // parse input into keyvalue container
 | 
|---|
| [5d30c1] | 1270 |   Ref<ParsedKeyVal> parsedkv;
 | 
|---|
| [516fb4] | 1271 |   int use_simple_input = 0; // default is object-oriented if in_char_array is given
 | 
|---|
 | 1272 |   if (!in_char_array) // obtain from file
 | 
|---|
 | 1273 |     parseInputfile(grp, parsedkv, values, input, generic_input, in_char_array, use_simple_input);
 | 
|---|
| [d2d7fc] | 1274 |   parseIntoKeyValue(parsedkv, values, in_char_array, use_simple_input);
 | 
|---|
 | 1275 |   delete[] in_char_array;
 | 
|---|
| [ce1e39] | 1276 | 
 | 
|---|
 | 1277 |   // prefix parsed values wit "mpqc"
 | 
|---|
| [ec4b04] | 1278 |   if (values.keyvalue) parsedkv->verbose(1);
 | 
|---|
| [5d30c1] | 1279 |   Ref<KeyVal> keyval = new PrefixKeyVal(parsedkv.pointer(),"mpqc");
 | 
|---|
 | 1280 | 
 | 
|---|
 | 1281 |   // set up output classes
 | 
|---|
| [8860a6] | 1282 |   setupSCFormIO(grp);
 | 
|---|
| [5d30c1] | 1283 | 
 | 
|---|
 | 1284 |   // initialize timing for mpqc
 | 
|---|
 | 1285 |   Ref<RegionTimer> tim;
 | 
|---|
| [c676ca] | 1286 |   initTimings(grp, keyval, tim);
 | 
|---|
| [5d30c1] | 1287 |   
 | 
|---|
 | 1288 |   // announce ourselves
 | 
|---|
| [3d4397] | 1289 |   makeAnnouncement(tim);
 | 
|---|
| [5d30c1] | 1290 | 
 | 
|---|
| [3cb97b] | 1291 |   // get the thread group.
 | 
|---|
 | 1292 |   Ref<ThreadGrp> thread;
 | 
|---|
 | 1293 |   getThreadGroup(keyval, thread, argc, argv);
 | 
|---|
| [4aba27] | 1294 | 
 | 
|---|
| [7ed4e8] | 1295 |   // get the memory group.
 | 
|---|
 | 1296 |   Ref<MemoryGrp> memory;
 | 
|---|
 | 1297 |   getMemoryGroup(keyval, memory, argc, argv);
 | 
|---|
| [5d30c1] | 1298 | 
 | 
|---|
 | 1299 |   ExEnv::out0() << indent
 | 
|---|
 | 1300 |        << "Using " << grp->class_name()
 | 
|---|
 | 1301 |        << " for message passing (number of nodes = " << grp->n() << ")." << endl
 | 
|---|
 | 1302 |        << indent
 | 
|---|
 | 1303 |        << "Using " << thread->class_name()
 | 
|---|
 | 1304 |        << " for threading (number of threads = " << thread->nthread() << ")." << endl
 | 
|---|
 | 1305 |        << indent
 | 
|---|
 | 1306 |        << "Using " << memory->class_name()
 | 
|---|
 | 1307 |        << " for distributed shared memory." << endl
 | 
|---|
 | 1308 |        << indent
 | 
|---|
 | 1309 |        << "Total number of processors = " << grp->n() * thread->nthread() << endl;
 | 
|---|
 | 1310 | 
 | 
|---|
| [666f70] | 1311 |   // prepare CCA if available
 | 
|---|
| [ec4b04] | 1312 |   prepareCCA(keyval, values);
 | 
|---|
| [5d30c1] | 1313 | 
 | 
|---|
 | 1314 |   // now set up the debugger
 | 
|---|
| [f5403d] | 1315 |   Ref<Debugger> debugger;
 | 
|---|
| [52aacc] | 1316 |   setupDebugger(keyval, grp, debugger, values);
 | 
|---|
| [5d30c1] | 1317 | 
 | 
|---|
 | 1318 |   // now check to see what matrix kit to use
 | 
|---|
 | 1319 |   if (keyval->exists("matrixkit"))
 | 
|---|
 | 1320 |     SCMatrixKit::set_default_matrixkit(
 | 
|---|
 | 1321 |       dynamic_cast<SCMatrixKit*>(
 | 
|---|
 | 1322 |         keyval->describedclassvalue("matrixkit").pointer()));
 | 
|---|
 | 1323 | 
 | 
|---|
| [09bc09] | 1324 |   // get the integral factory.
 | 
|---|
 | 1325 |   Ref<Integral> integral;
 | 
|---|
 | 1326 |   getIntegralFactory(keyval, integral, argc, argv);
 | 
|---|
| [5d30c1] | 1327 |   ExEnv::out0() << endl << indent
 | 
|---|
 | 1328 |        << "Using " << integral->class_name()
 | 
|---|
 | 1329 |        << " by default for molecular integrals evaluation" << endl << endl;
 | 
|---|
 | 1330 |   
 | 
|---|
| [d392067] | 1331 |   // create some filenames for molecule, checkpoint, basename of output
 | 
|---|
| [203fe4] | 1332 |   const char *basename = SCFormIO::default_basename();
 | 
|---|
| [5d30c1] | 1333 |   KeyValValueString molnamedef(basename);
 | 
|---|
 | 1334 |   char * molname = keyval->pcharvalue("filename", molnamedef);
 | 
|---|
 | 1335 |   if (strcmp(molname, basename))
 | 
|---|
 | 1336 |     SCFormIO::set_default_basename(molname);
 | 
|---|
 | 1337 | 
 | 
|---|
 | 1338 |   char * ckptfile = new char[strlen(molname)+6];
 | 
|---|
 | 1339 |   sprintf(ckptfile,"%s.ckpt",molname);
 | 
|---|
| [42a775] | 1340 | 
 | 
|---|
| [5d30c1] | 1341 |   KeyValValueString restartfiledef(ckptfile);
 | 
|---|
 | 1342 |   char * restartfile = keyval->pcharvalue("restart_file", restartfiledef);
 | 
|---|
 | 1343 |   
 | 
|---|
 | 1344 |   char * wfn_file = keyval->pcharvalue("wfn_file");
 | 
|---|
 | 1345 |   if (wfn_file == 0) {
 | 
|---|
 | 1346 |     wfn_file = new char[strlen(molname)+6];
 | 
|---|
 | 1347 |     sprintf(wfn_file,"%s.wfn",molname);
 | 
|---|
 | 1348 |   }
 | 
|---|
 | 1349 |   char *mole_ckpt_file = new char[strlen(wfn_file)+1];
 | 
|---|
 | 1350 |   sprintf(mole_ckpt_file,"%s",wfn_file);
 | 
|---|
 | 1351 | 
 | 
|---|
 | 1352 |   int savestate = keyval->booleanvalue("savestate",truevalue);
 | 
|---|
 | 1353 | 
 | 
|---|
| [9b827f] | 1354 |   // setup molecular energy and optimization instances
 | 
|---|
| [5d30c1] | 1355 |   Ref<MolecularEnergy> mole;
 | 
|---|
 | 1356 |   Ref<Optimize> opt;
 | 
|---|
 | 1357 | 
 | 
|---|
| [9b827f] | 1358 |   // read in restart file if we do restart
 | 
|---|
| [666f70] | 1359 |   performRestart(keyval, grp, opt, mole, restartfile);
 | 
|---|
| [5d30c1] | 1360 | 
 | 
|---|
| [9b827f] | 1361 |   // setup molecule checkpoint file
 | 
|---|
 | 1362 |   setMolecularCheckpointFile(keyval, grp, mole, mole_ckpt_file);
 | 
|---|
| [5d30c1] | 1363 |   delete[] mole_ckpt_file;
 | 
|---|
 | 1364 | 
 | 
|---|
| [42a775] | 1365 |   int checkpoint = keyval->booleanvalue("checkpoint",truevalue);
 | 
|---|
| [5d30c1] | 1366 |   if (checkpoint && opt.nonnull()) {
 | 
|---|
 | 1367 |     opt->set_checkpoint();
 | 
|---|
 | 1368 |     if (grp->me() == 0) opt->set_checkpoint_file(ckptfile);
 | 
|---|
 | 1369 |     else opt->set_checkpoint_file(devnull);
 | 
|---|
 | 1370 |   }
 | 
|---|
 | 1371 | 
 | 
|---|
 | 1372 |   // see if frequencies are wanted
 | 
|---|
 | 1373 |   Ref<MolecularHessian> molhess;
 | 
|---|
 | 1374 |   molhess << keyval->describedclassvalue("hess");
 | 
|---|
 | 1375 |   Ref<MolecularFrequencies> molfreq;
 | 
|---|
 | 1376 |   molfreq << keyval->describedclassvalue("freq");
 | 
|---|
 | 1377 | 
 | 
|---|
| [05c6bc] | 1378 |   // check basis set limit
 | 
|---|
| [ec4b04] | 1379 |   const int check = checkBasisSetLimit(mole, values);
 | 
|---|
| [5d30c1] | 1380 |   if (check) {
 | 
|---|
 | 1381 |     ExEnv::out0() << endl << indent
 | 
|---|
 | 1382 |          << "Exiting since the check option is on." << endl;
 | 
|---|
 | 1383 |     exit(0);
 | 
|---|
 | 1384 |   }
 | 
|---|
 | 1385 |   
 | 
|---|
| [42a775] | 1386 |   // from now on we time the calculations
 | 
|---|
| [5d30c1] | 1387 |   if (tim.nonnull()) tim->change("calc");
 | 
|---|
 | 1388 | 
 | 
|---|
 | 1389 |   int do_energy = keyval->booleanvalue("do_energy",truevalue);
 | 
|---|
| [d39b2b] | 1390 | 
 | 
|---|
| [5d30c1] | 1391 |   int do_grad = keyval->booleanvalue("do_gradient",falsevalue);
 | 
|---|
 | 1392 | 
 | 
|---|
 | 1393 |   int do_opt = keyval->booleanvalue("optimize",truevalue);
 | 
|---|
| [d39b2b] | 1394 | 
 | 
|---|
| [5d30c1] | 1395 |   int do_pdb = keyval->booleanvalue("write_pdb",falsevalue);
 | 
|---|
| [d39b2b] | 1396 | 
 | 
|---|
| [5d30c1] | 1397 |   int print_mole = keyval->booleanvalue("print_mole",truevalue);
 | 
|---|
| [d39b2b] | 1398 | 
 | 
|---|
| [5d30c1] | 1399 |   int print_timings = keyval->booleanvalue("print_timings",truevalue);
 | 
|---|
 | 1400 | 
 | 
|---|
| [d39b2b] | 1401 |   // print all current options (keyvalues)
 | 
|---|
 | 1402 |   printOptions(keyval, opt, molname, restartfile);
 | 
|---|
 | 1403 | 
 | 
|---|
| [5d30c1] | 1404 |   // see if any pictures are desired
 | 
|---|
 | 1405 |   Ref<Render> renderer;
 | 
|---|
 | 1406 |   renderer << keyval->describedclassvalue("renderer");
 | 
|---|
 | 1407 | 
 | 
|---|
 | 1408 |   // If we have a renderer, then we will read in some more info
 | 
|---|
 | 1409 |   // below.  Otherwise we can get rid of the keyval's, to eliminate
 | 
|---|
 | 1410 |   // superfluous references to objects that we might otherwise be
 | 
|---|
 | 1411 |   // able to delete.  We cannot read in the remaining rendering
 | 
|---|
 | 1412 |   // objects now, since some of their KeyVal CTOR's are heavyweight,
 | 
|---|
 | 1413 |   // requiring optimized geometries, etc.
 | 
|---|
 | 1414 |   if (renderer.null()) {
 | 
|---|
 | 1415 |     if (parsedkv.nonnull()) print_unseen(parsedkv, input);
 | 
|---|
 | 1416 |     keyval = 0;
 | 
|---|
 | 1417 |     parsedkv = 0;
 | 
|---|
 | 1418 |   }
 | 
|---|
 | 1419 | 
 | 
|---|
 | 1420 |   delete[] restartfile;
 | 
|---|
 | 1421 |   delete[] ckptfile;
 | 
|---|
 | 1422 | 
 | 
|---|
 | 1423 |   int ready_for_freq = 1;
 | 
|---|
 | 1424 |   if (mole.nonnull()) {
 | 
|---|
 | 1425 |     if (((do_opt && opt.nonnull()) || do_grad)
 | 
|---|
 | 1426 |         && !mole->gradient_implemented()) {
 | 
|---|
 | 1427 |       ExEnv::out0() << indent
 | 
|---|
 | 1428 |            << "WARNING: optimization or gradient requested but the given"
 | 
|---|
 | 1429 |            << endl
 | 
|---|
 | 1430 |            << "         MolecularEnergy object cannot do gradients."
 | 
|---|
 | 1431 |            << endl;
 | 
|---|
 | 1432 |     }
 | 
|---|
 | 1433 | 
 | 
|---|
 | 1434 |     if (do_opt && opt.nonnull() && mole->gradient_implemented()) {
 | 
|---|
| [ad2befa] | 1435 | 
 | 
|---|
 | 1436 |       ready_for_freq = performEnergyOptimization(opt, mole);
 | 
|---|
 | 1437 | 
 | 
|---|
| [5d30c1] | 1438 |     } else if (do_grad && mole->gradient_implemented()) {
 | 
|---|
| [d392067] | 1439 | 
 | 
|---|
 | 1440 |       performGradientCalculation(mole);
 | 
|---|
 | 1441 | 
 | 
|---|
| [5d30c1] | 1442 |     } else if (do_energy && mole->value_implemented()) {
 | 
|---|
 | 1443 |       ExEnv::out0() << endl << indent
 | 
|---|
 | 1444 |            << scprintf("Value of the MolecularEnergy: %15.10f",
 | 
|---|
 | 1445 |                        mole->energy())
 | 
|---|
 | 1446 |            << endl << endl;
 | 
|---|
 | 1447 |     }
 | 
|---|
 | 1448 |   }
 | 
|---|
 | 1449 | 
 | 
|---|
| [d392067] | 1450 |   // stop timing of calculations
 | 
|---|
| [5d30c1] | 1451 |   if (tim.nonnull()) tim->exit("calc");
 | 
|---|
 | 1452 | 
 | 
|---|
 | 1453 |   // save this before doing the frequency stuff since that obsoletes the
 | 
|---|
| [a98b86] | 1454 |   saveState(wfn_file, savestate, opt, grp, mole, molname, ckptfile);
 | 
|---|
| [5d30c1] | 1455 |   
 | 
|---|
 | 1456 |   // Frequency calculation.
 | 
|---|
 | 1457 |   if (ready_for_freq && molfreq.nonnull()) {
 | 
|---|
| [bab0b1] | 1458 |     performFrequencyCalculation(mole, molhess, molfreq);
 | 
|---|
| [5d30c1] | 1459 |   }
 | 
|---|
 | 1460 | 
 | 
|---|
 | 1461 |   if (renderer.nonnull()) {
 | 
|---|
| [5ef341] | 1462 |     renderObjects(renderer, keyval, tim, grp);
 | 
|---|
 | 1463 | 
 | 
|---|
| [5d30c1] | 1464 |     Ref<MolFreqAnimate> molfreqanim;
 | 
|---|
 | 1465 |     molfreqanim << keyval->describedclassvalue("animate_modes");
 | 
|---|
 | 1466 |     if (ready_for_freq && molfreq.nonnull()
 | 
|---|
 | 1467 |         && molfreqanim.nonnull()) {
 | 
|---|
 | 1468 |       if (tim.nonnull()) tim->enter("render");
 | 
|---|
 | 1469 |       molfreq->animate(renderer, molfreqanim);
 | 
|---|
 | 1470 |       if (tim.nonnull()) tim->exit("render");
 | 
|---|
 | 1471 |     }
 | 
|---|
 | 1472 |   }
 | 
|---|
 | 1473 | 
 | 
|---|
 | 1474 |   if (mole.nonnull()) {
 | 
|---|
 | 1475 |     if (print_mole)
 | 
|---|
 | 1476 |       mole->print(ExEnv::out0());
 | 
|---|
 | 1477 | 
 | 
|---|
| [e9a571] | 1478 |     saveToPdb(do_pdb, grp, mole, molname);
 | 
|---|
 | 1479 | 
 | 
|---|
| [5d30c1] | 1480 |   }
 | 
|---|
 | 1481 |   else {
 | 
|---|
 | 1482 |     ExEnv::out0() << "mpqc: The molecular energy object is null" << endl
 | 
|---|
 | 1483 |          << " make sure \"mole\" specifies a MolecularEnergy derivative"
 | 
|---|
 | 1484 |          << endl;
 | 
|---|
 | 1485 |   }
 | 
|---|
 | 1486 |   if (parsedkv.nonnull()) print_unseen(parsedkv, input);
 | 
|---|
 | 1487 | 
 | 
|---|
| [027140] | 1488 |   // here, we may gather the results
 | 
|---|
| [850bce] | 1489 |   // we start to fill the MPQC_Data object
 | 
|---|
| [f0da45] | 1490 |   if (tim.nonnull()) tim->enter("gather");
 | 
|---|
| [027140] | 1491 |   {
 | 
|---|
 | 1492 |      Ref<Wavefunction> wfn;
 | 
|---|
 | 1493 |      wfn << mole;
 | 
|---|
| [737c47] | 1494 | //     ExEnv::out0() << "The number of atomic orbitals: " << wfn->ao_dimension()->n() << endl;
 | 
|---|
 | 1495 | //     ExEnv::out0() << "The AO density matrix is ";
 | 
|---|
 | 1496 | //     wfn->ao_density()->print(ExEnv::out0());
 | 
|---|
 | 1497 | //     ExEnv::out0() << "The natural density matrix is ";
 | 
|---|
 | 1498 | //     wfn->natural_density()->print(ExEnv::out0());
 | 
|---|
 | 1499 | //     ExEnv::out0() << "The Gaussian basis is " << wfn->basis()->name() << endl;
 | 
|---|
 | 1500 | //     ExEnv::out0() << "The Gaussians sit at the following centers: " << endl;
 | 
|---|
 | 1501 | //     for (int nr = 0; nr< wfn->basis()->ncenter(); ++nr) {
 | 
|---|
 | 1502 | //       ExEnv::out0() << nr << " basis function has its center at ";
 | 
|---|
 | 1503 | //       for (int i=0; i < 3; ++i)
 | 
|---|
 | 1504 | //           ExEnv::out0() << wfn->basis()->r(nr,i) << "\t";
 | 
|---|
 | 1505 | //       ExEnv::out0() << endl;
 | 
|---|
 | 1506 | //     }
 | 
|---|
| [850bce] | 1507 |      // print the energy
 | 
|---|
| [f0da45] | 1508 |      data.energies.total = wfn->energy();
 | 
|---|
| [16135f] | 1509 |      data.energies.nuclear_repulsion = wfn->nuclear_repulsion_energy();
 | 
|---|
 | 1510 |      {
 | 
|---|
| [1ed5fc] | 1511 |        CLHF *clhf = dynamic_cast<CLHF*>(wfn.pointer());
 | 
|---|
 | 1512 |        if (clhf != NULL) {
 | 
|---|
 | 1513 |          double ex, ec;
 | 
|---|
 | 1514 |          clhf->two_body_energy(ec, ex);
 | 
|---|
 | 1515 |          data.energies.electron_coulomb = ec;
 | 
|---|
 | 1516 |          data.energies.electron_exchange = ex;
 | 
|---|
 | 1517 |          clhf = NULL;
 | 
|---|
 | 1518 |        } else {
 | 
|---|
 | 1519 |          ExEnv::out0() << "INFO: There is no CLHF information available." << endl;
 | 
|---|
 | 1520 |          data.energies.electron_coulomb = 0.;
 | 
|---|
 | 1521 |          data.energies.electron_exchange = 0.;
 | 
|---|
 | 1522 |        }
 | 
|---|
 | 1523 |      }
 | 
|---|
| [d901f7] | 1524 |      SCF *scf = NULL;
 | 
|---|
| [1ed5fc] | 1525 |      {
 | 
|---|
 | 1526 |        MBPT2 *mbpt2 = dynamic_cast<MBPT2*>(wfn.pointer());
 | 
|---|
 | 1527 |        if (mbpt2 != NULL) {
 | 
|---|
 | 1528 |          data.energies.correlation = mbpt2->corr_energy();
 | 
|---|
| [d901f7] | 1529 |          scf = mbpt2->ref().pointer();
 | 
|---|
| [1ed5fc] | 1530 |          mbpt2 = 0;
 | 
|---|
 | 1531 |        } else {
 | 
|---|
 | 1532 |          ExEnv::out0() << "INFO: There is no MBPT2 information available." << endl;
 | 
|---|
 | 1533 |          data.energies.correlation = 0.;
 | 
|---|
| [d901f7] | 1534 |          scf = dynamic_cast<SCF*>(wfn.pointer());
 | 
|---|
 | 1535 |          if (scf == NULL)
 | 
|---|
 | 1536 |            abort();
 | 
|---|
| [1ed5fc] | 1537 |        }
 | 
|---|
 | 1538 |      }
 | 
|---|
 | 1539 |      {
 | 
|---|
 | 1540 |        // taken from clscf.cc: CLSCF::scf_energy() (but see also Szabo/Ostlund)
 | 
|---|
| [d901f7] | 1541 | 
 | 
|---|
 | 1542 |        RefSymmSCMatrix t = scf->overlap();
 | 
|---|
 | 1543 |        RefSymmSCMatrix cl_dens_ = scf->ao_density();
 | 
|---|
| [16135f] | 1544 | 
 | 
|---|
 | 1545 |        SCFEnergy *eop = new SCFEnergy;
 | 
|---|
 | 1546 |        eop->reference();
 | 
|---|
 | 1547 |        Ref<SCElementOp2> op = eop;
 | 
|---|
 | 1548 |        t.element_op(op,cl_dens_);
 | 
|---|
 | 1549 |        op=0;
 | 
|---|
 | 1550 |        eop->dereference();
 | 
|---|
 | 1551 | 
 | 
|---|
 | 1552 |        data.energies.overlap = eop->result();
 | 
|---|
 | 1553 | 
 | 
|---|
 | 1554 |        delete eop;
 | 
|---|
 | 1555 |        t = 0;
 | 
|---|
 | 1556 |        cl_dens_ = 0;
 | 
|---|
 | 1557 |      }
 | 
|---|
| [1ed5fc] | 1558 |      {
 | 
|---|
 | 1559 |        // taken from Wavefunction::core_hamiltonian()
 | 
|---|
| [d901f7] | 1560 |        RefSymmSCMatrix hao(scf->basis()->basisdim(), scf->basis()->matrixkit());
 | 
|---|
| [1ed5fc] | 1561 |        hao.assign(0.0);
 | 
|---|
| [d901f7] | 1562 |        Ref<PetiteList> pl = scf->integral()->petite_list();
 | 
|---|
| [1ed5fc] | 1563 |        Ref<SCElementOp> hc =
 | 
|---|
| [d901f7] | 1564 |          new OneBodyIntOp(new SymmOneBodyIntIter(scf->integral()->kinetic(), pl));
 | 
|---|
| [1ed5fc] | 1565 |        hao.element_op(hc);
 | 
|---|
 | 1566 |        hc=0;
 | 
|---|
 | 1567 | 
 | 
|---|
| [d901f7] | 1568 |        RefSymmSCMatrix h(scf->so_dimension(), scf->basis_matrixkit());
 | 
|---|
| [1ed5fc] | 1569 |        pl->symmetrize(hao,h);
 | 
|---|
 | 1570 | 
 | 
|---|
 | 1571 |        // taken from clscf.cc: CLSCF::scf_energy() (but see also Szabo/Ostlund)
 | 
|---|
| [d901f7] | 1572 |        RefSymmSCMatrix cl_dens_ = scf->ao_density();
 | 
|---|
| [1ed5fc] | 1573 | 
 | 
|---|
 | 1574 |        SCFEnergy *eop = new SCFEnergy;
 | 
|---|
 | 1575 |        eop->reference();
 | 
|---|
 | 1576 |        Ref<SCElementOp2> op = eop;
 | 
|---|
 | 1577 |        h.element_op(op,cl_dens_);
 | 
|---|
 | 1578 |        op=0;
 | 
|---|
 | 1579 |        eop->dereference();
 | 
|---|
 | 1580 | 
 | 
|---|
 | 1581 |        data.energies.kinetic = eop->result();
 | 
|---|
 | 1582 | 
 | 
|---|
 | 1583 |        delete eop;
 | 
|---|
 | 1584 |        hao = 0;
 | 
|---|
 | 1585 |        h = 0;
 | 
|---|
 | 1586 |        cl_dens_ = 0;
 | 
|---|
 | 1587 |      }
 | 
|---|
| [16135f] | 1588 |      {
 | 
|---|
| [b88be2] | 1589 |        data.energies.hcore = scf->one_body_energy();
 | 
|---|
| [16135f] | 1590 |      }
 | 
|---|
| [850bce] | 1591 |      ExEnv::out0() << endl << indent
 | 
|---|
 | 1592 |           << scprintf("Value of the MolecularEnergy: %15.10f",
 | 
|---|
 | 1593 |                       mole->energy())
 | 
|---|
 | 1594 |           << endl;
 | 
|---|
 | 1595 |      // print the gradient
 | 
|---|
 | 1596 |      RefSCVector grad;
 | 
|---|
 | 1597 |      if (mole->gradient_result().computed()) {
 | 
|---|
 | 1598 |        grad = mole->gradient_result().result_noupdate();
 | 
|---|
 | 1599 |      }
 | 
|---|
 | 1600 |      else {
 | 
|---|
 | 1601 |        grad = mole->gradient();
 | 
|---|
 | 1602 |      }
 | 
|---|
 | 1603 |      if (grad.nonnull()) {
 | 
|---|
 | 1604 |        data.forces.resize(grad.dim()/3);
 | 
|---|
 | 1605 |        for (int j=0;j<grad.dim()/3; ++j) {
 | 
|---|
| [737c47] | 1606 |          data.forces[j].resize(3, 0.);
 | 
|---|
| [850bce] | 1607 |        }
 | 
|---|
 | 1608 |        std::cout << "Gradient of the MolecularEnergy:" << std::endl;
 | 
|---|
 | 1609 |        for (int j=0;j<grad.dim()/3; ++j) {
 | 
|---|
 | 1610 |          std::cout << "\t";
 | 
|---|
 | 1611 |          for (int i=0; i< 3; ++i) {
 | 
|---|
 | 1612 |            data.forces[j][i] = grad[3*j+i];
 | 
|---|
 | 1613 |            std::cout << grad[3*j+i] << "\t";
 | 
|---|
 | 1614 |          }
 | 
|---|
 | 1615 |          std::cout << endl;
 | 
|---|
 | 1616 |        }
 | 
|---|
 | 1617 |      }
 | 
|---|
| [d901f7] | 1618 |      grad = NULL;
 | 
|---|
| [e144c8] | 1619 | 
 | 
|---|
| [1ed5fc] | 1620 |      {
 | 
|---|
 | 1621 |        // eigenvalues (this only works if we have a OneBodyWavefunction, i.e. SCF procedure)
 | 
|---|
| [fd6273] | 1622 | //       SCF *scf = dynamic_cast<SCF*>(wfn.pointer());
 | 
|---|
 | 1623 | //       if (scf != NULL) {
 | 
|---|
 | 1624 | //         const double scfernergy = scf->energy();
 | 
|---|
| [1ed5fc] | 1625 |          RefDiagSCMatrix evals = scf->eigenvalues();
 | 
|---|
 | 1626 | 
 | 
|---|
 | 1627 |          for(int i=0;i<wfn->oso_dimension(); ++i) {
 | 
|---|
 | 1628 |            data.energies.eigenvalues.push_back(evals(i));
 | 
|---|
 | 1629 |            //std::cout << i << "th eigenvalue is " << evals(i) << std::endl;
 | 
|---|
 | 1630 |          }
 | 
|---|
| [fd6273] | 1631 | //       }
 | 
|---|
| [6bf68b] | 1632 |      }
 | 
|---|
| [d901f7] | 1633 |      {
 | 
|---|
| [89ced8] | 1634 |        // fill positions and charges (NO LONGER converting from bohr radii to angstroem)
 | 
|---|
 | 1635 |        const double AtomicLengthToAngstroem = 1.;//0.52917721;
 | 
|---|
| [d901f7] | 1636 |        data.positions.reserve(wfn->molecule()->natom());
 | 
|---|
 | 1637 |        data.charges.reserve(wfn->molecule()->natom());
 | 
|---|
 | 1638 |        for (int iatom=0;iatom < wfn->molecule()->natom(); ++iatom) {
 | 
|---|
 | 1639 |          data.charges.push_back(wfn->molecule()->Z(iatom));
 | 
|---|
 | 1640 |          std::vector<double> pos(3, 0.);
 | 
|---|
 | 1641 |          for (int j=0;j<3;++j)
 | 
|---|
| [4dfef04] | 1642 |            pos[j] = wfn->molecule()->r(iatom, j)*AtomicLengthToAngstroem;
 | 
|---|
| [d901f7] | 1643 |          data.positions.push_back(pos);
 | 
|---|
 | 1644 |        }
 | 
|---|
 | 1645 |        std::cout << "We have "
 | 
|---|
 | 1646 |            << data.positions.size() << " positions and "
 | 
|---|
 | 1647 |            << data.charges.size() << " charges." << std::endl;
 | 
|---|
 | 1648 |      }
 | 
|---|
| [cd2e34] | 1649 |      if (data.sampled_grid.level != 0)
 | 
|---|
| [1ed5fc] | 1650 |      {
 | 
|---|
 | 1651 |        // we now need to sample the density on the grid
 | 
|---|
 | 1652 |        // 1. get max and min over all basis function positions
 | 
|---|
| [d901f7] | 1653 |        assert( scf->basis()->ncenter() > 0 );
 | 
|---|
 | 1654 |        SCVector3 bmin( scf->basis()->r(0,0), scf->basis()->r(0,1), scf->basis()->r(0,2) );
 | 
|---|
 | 1655 |        SCVector3 bmax( scf->basis()->r(0,0), scf->basis()->r(0,1), scf->basis()->r(0,2) );
 | 
|---|
 | 1656 |        for (int nr = 1; nr< scf->basis()->ncenter(); ++nr) {
 | 
|---|
| [1ed5fc] | 1657 |          for (int i=0; i < 3; ++i) {
 | 
|---|
| [d901f7] | 1658 |            if (scf->basis()->r(nr,i) < bmin(i))
 | 
|---|
 | 1659 |              bmin(i) = scf->basis()->r(nr,i);
 | 
|---|
 | 1660 |            if (scf->basis()->r(nr,i) > bmax(i))
 | 
|---|
 | 1661 |              bmax(i) = scf->basis()->r(nr,i);
 | 
|---|
| [6bf68b] | 1662 |          }
 | 
|---|
| [1ed5fc] | 1663 |        }
 | 
|---|
| [d901f7] | 1664 |        std::cout << "Basis min is at " << bmin << " and max is at " << bmax << std::endl;
 | 
|---|
| [1ed5fc] | 1665 | 
 | 
|---|
 | 1666 |        // 2. choose an appropriately large grid
 | 
|---|
 | 1667 |        // we have to pay attention to capture the right amount of the exponential decay
 | 
|---|
 | 1668 |        // and also to have a power of two size of the grid at best
 | 
|---|
| [3ad723] | 1669 |        SCVector3 boundaryV(5.);  // boundary extent around compact domain containing basis functions
 | 
|---|
 | 1670 |        bmin -= boundaryV;
 | 
|---|
 | 1671 |        bmax += boundaryV;
 | 
|---|
 | 1672 |        for (size_t i=0;i<3;++i) {
 | 
|---|
 | 1673 |          if (bmin(i) < data.sampled_grid.begin[i])
 | 
|---|
 | 1674 |            bmin(i) = data.sampled_grid.begin[i];
 | 
|---|
 | 1675 |          if (bmax(i) > data.sampled_grid.end[i])
 | 
|---|
 | 1676 |            bmax(i) = data.sampled_grid.end[i];
 | 
|---|
 | 1677 |        }
 | 
|---|
 | 1678 |        // set the non-zero window of the sampled_grid
 | 
|---|
 | 1679 |        data.sampled_grid.setWindow(bmin.data(), bmax.data());
 | 
|---|
| [1ed5fc] | 1680 | 
 | 
|---|
 | 1681 |        // for the moment we always generate a grid of full size
 | 
|---|
| [89ced8] | 1682 |        // (NO LONGER converting grid dimensions from angstroem to bohr radii)
 | 
|---|
 | 1683 |        const double AtomicLengthToAngstroem = 1.;//0.52917721;
 | 
|---|
| [d901f7] | 1684 |        SCVector3 min;
 | 
|---|
 | 1685 |        SCVector3 max;
 | 
|---|
| [3ad723] | 1686 |        SCVector3 delta;
 | 
|---|
 | 1687 |        SCVector3 samplepoints;
 | 
|---|
 | 1688 |        SCVector3 length;
 | 
|---|
 | 1689 |        SCVector3 total;
 | 
|---|
| [debc65] | 1690 |        // due to periodic boundary conditions, we don't need gridpoints-1 here
 | 
|---|
 | 1691 |        // TODO: in case of open boundary conditions, we need data on the right
 | 
|---|
 | 1692 |        // hand side boundary as well
 | 
|---|
| [3ad723] | 1693 |        const int gridpoints = data.sampled_grid.getGridPointsPerAxis();
 | 
|---|
 | 1694 |        for (size_t i=0;i<3;++i) {
 | 
|---|
 | 1695 |          min(i) = bmin(i)/AtomicLengthToAngstroem;
 | 
|---|
 | 1696 |          max(i) = bmax(i)/AtomicLengthToAngstroem;
 | 
|---|
 | 1697 |          length(i) = bmax(i) - bmin(i);
 | 
|---|
 | 1698 |          total(i) = data.sampled_grid.end[i] - data.sampled_grid.begin[i];
 | 
|---|
 | 1699 |          delta(i) = total(i)/AtomicLengthToAngstroem/(double)gridpoints;
 | 
|---|
 | 1700 |          samplepoints(i) = floor(gridpoints*(length(i)/total(i))/AtomicLengthToAngstroem)+1;
 | 
|---|
 | 1701 |        }
 | 
|---|
| [1ed5fc] | 1702 |        std::cout << "Grid starts at " << min
 | 
|---|
 | 1703 |            << " and ends at " << max
 | 
|---|
 | 1704 |            << " with a delta of " << delta
 | 
|---|
| [3ad723] | 1705 |            << " to get " << samplepoints << " samplepoints."
 | 
|---|
| [1ed5fc] | 1706 |            << std::endl;
 | 
|---|
| [3ad723] | 1707 |        assert( data.sampled_grid.sampled_grid.size() == samplepoints(0)*samplepoints(1)*samplepoints(2));
 | 
|---|
| [1ed5fc] | 1708 | 
 | 
|---|
 | 1709 |        // 3. sample the atomic density
 | 
|---|
| [4dfef04] | 1710 |        const double element_volume_conversion =
 | 
|---|
 | 1711 |            1./AtomicLengthToAngstroem/AtomicLengthToAngstroem/AtomicLengthToAngstroem;
 | 
|---|
| [3ad723] | 1712 |        SCVector3 r = min;
 | 
|---|
 | 1713 |        std::vector<double>::iterator griditer = data.sampled_grid.sampled_grid.begin();
 | 
|---|
 | 1714 |        for (size_t x = 0; x < samplepoints(0); ++x, r.x() += delta(0)) {
 | 
|---|
| [d901f7] | 1715 |          std::cout << "Sampling now for x=" << r.x() << std::endl;
 | 
|---|
| [3ad723] | 1716 |          for (size_t y = 0; y < samplepoints(1); ++y, r.y() += delta(1)) {
 | 
|---|
 | 1717 |            for (size_t z = 0; z < samplepoints(2); ++z, r.z() += delta(2)) {
 | 
|---|
 | 1718 |              const double dens_at_r = scf->density(r) * element_volume_conversion;
 | 
|---|
 | 1719 | //             if (fabs(dens_at_r) > 1e-4)
 | 
|---|
 | 1720 | //               std::cout << "Electron density at " << r << " is " << dens_at_r << std::endl;
 | 
|---|
 | 1721 |              if (griditer != data.sampled_grid.sampled_grid.end())
 | 
|---|
 | 1722 |                *griditer++ = dens_at_r;
 | 
|---|
 | 1723 |              else
 | 
|---|
 | 1724 |                std::cerr << "PAST RANGE!" << std::endl;
 | 
|---|
| [1ed5fc] | 1725 |            }
 | 
|---|
| [4dfef04] | 1726 |            r.z() = min.z();
 | 
|---|
 | 1727 |          }
 | 
|---|
 | 1728 |          r.y() = min.y();
 | 
|---|
 | 1729 |        }
 | 
|---|
| [3ad723] | 1730 |        assert( griditer == data.sampled_grid.sampled_grid.end());
 | 
|---|
| [4dfef04] | 1731 |        // normalization of electron charge to equal electron number
 | 
|---|
 | 1732 |        {
 | 
|---|
 | 1733 |          double integral_value = 0.;
 | 
|---|
| [3ad723] | 1734 |          const double volume_element = pow(AtomicLengthToAngstroem,3)*delta(0)*delta(1)*delta(2);
 | 
|---|
| [4dfef04] | 1735 |          for (std::vector<double>::const_iterator diter = data.sampled_grid.sampled_grid.begin();
 | 
|---|
 | 1736 |              diter != data.sampled_grid.sampled_grid.end(); ++diter)
 | 
|---|
 | 1737 |              integral_value += *diter;
 | 
|---|
| [3ad723] | 1738 |          integral_value *= volume_element;
 | 
|---|
| [debc65] | 1739 |          const double normalization =
 | 
|---|
 | 1740 |              ((integral_value == 0) && (scf->nelectron() == 0)) ?
 | 
|---|
 | 1741 |                  1. : scf->nelectron()/integral_value;
 | 
|---|
| [3ad723] | 1742 |          std::cout << "Created " << data.sampled_grid.sampled_grid.size() << " grid points"
 | 
|---|
| [4dfef04] | 1743 |              << " with integral value of " << integral_value
 | 
|---|
 | 1744 |              << " against nelectron of " << scf->nelectron() << "." << std::endl;
 | 
|---|
 | 1745 |          for (std::vector<double>::iterator diter = data.sampled_grid.sampled_grid.begin();
 | 
|---|
 | 1746 |              diter != data.sampled_grid.sampled_grid.end(); ++diter)
 | 
|---|
 | 1747 |              *diter *= normalization;
 | 
|---|
| [d901f7] | 1748 |        }
 | 
|---|
| [1ed5fc] | 1749 |      }
 | 
|---|
| [d901f7] | 1750 |      scf = 0;
 | 
|---|
| [027140] | 1751 |   }
 | 
|---|
| [f137f7] | 1752 |   if (tim.nonnull()) tim->exit("gather");
 | 
|---|
 | 1753 | 
 | 
|---|
 | 1754 |   if (print_timings)
 | 
|---|
 | 1755 |     if (tim.nonnull()) tim->print(ExEnv::out0());
 | 
|---|
 | 1756 | 
 | 
|---|
 | 1757 | 
 | 
|---|
 | 1758 |   {
 | 
|---|
 | 1759 |     // times obtain from key "mpqc" which should be the first
 | 
|---|
 | 1760 |     const int nregion = tim->nregion();
 | 
|---|
 | 1761 |     //std::cout << "There are " << nregion << " timed regions." << std::endl;
 | 
|---|
 | 1762 |     const char **region_names = new const char*[nregion];
 | 
|---|
 | 1763 |     tim->get_region_names(region_names);
 | 
|---|
 | 1764 |     // find "gather"
 | 
|---|
 | 1765 |     size_t gather_region = findTimerRegion(nregion, region_names, "gather");
 | 
|---|
 | 1766 |     size_t mpqc_region = findTimerRegion(nregion, region_names, "mpqc");
 | 
|---|
 | 1767 | 
 | 
|---|
 | 1768 |     // get timings
 | 
|---|
 | 1769 |     double *cpu_time = new double[nregion];
 | 
|---|
 | 1770 |     double *wall_time = new double[nregion];
 | 
|---|
 | 1771 |     double *flops = new double[nregion];
 | 
|---|
 | 1772 |     tim->get_cpu_times(cpu_time);
 | 
|---|
 | 1773 |     tim->get_wall_times(wall_time);
 | 
|---|
 | 1774 |     tim->get_flops(flops);
 | 
|---|
 | 1775 |     if (cpu_time != NULL) {
 | 
|---|
 | 1776 |       data.times.total_cputime = cpu_time[mpqc_region];
 | 
|---|
 | 1777 |       data.times.gather_cputime = cpu_time[gather_region];
 | 
|---|
 | 1778 |     }
 | 
|---|
 | 1779 |     if (wall_time != NULL) {
 | 
|---|
 | 1780 |       data.times.total_walltime = wall_time[mpqc_region];
 | 
|---|
 | 1781 |       data.times.gather_walltime = wall_time[gather_region];
 | 
|---|
 | 1782 |     }
 | 
|---|
 | 1783 |     if (flops != NULL) {
 | 
|---|
 | 1784 |       data.times.total_flops = flops[mpqc_region];
 | 
|---|
 | 1785 |       data.times.gather_flops = flops[gather_region];
 | 
|---|
 | 1786 |     }
 | 
|---|
 | 1787 |     delete[] cpu_time;
 | 
|---|
 | 1788 |     delete[] wall_time;
 | 
|---|
 | 1789 |     delete[] flops;
 | 
|---|
 | 1790 |   }
 | 
|---|
| [027140] | 1791 | 
 | 
|---|
| [5d30c1] | 1792 |   delete[] molname;
 | 
|---|
 | 1793 |   SCFormIO::set_default_basename(0);
 | 
|---|
 | 1794 | 
 | 
|---|
 | 1795 |   renderer = 0;
 | 
|---|
 | 1796 |   molfreq = 0;
 | 
|---|
 | 1797 |   molhess = 0;
 | 
|---|
 | 1798 |   opt = 0;
 | 
|---|
 | 1799 |   mole = 0;
 | 
|---|
 | 1800 |   integral = 0;
 | 
|---|
 | 1801 |   debugger = 0;
 | 
|---|
 | 1802 |   thread = 0;
 | 
|---|
 | 1803 |   tim = 0;
 | 
|---|
 | 1804 |   keyval = 0;
 | 
|---|
 | 1805 |   parsedkv = 0;
 | 
|---|
 | 1806 |   memory = 0;
 | 
|---|
 | 1807 |   clean_up();
 | 
|---|
 | 1808 | 
 | 
|---|
 | 1809 | #if defined(HAVE_TIME) && defined(HAVE_CTIME)
 | 
|---|
| [3d4397] | 1810 |   time_t t;
 | 
|---|
| [5d30c1] | 1811 |   time(&t);
 | 
|---|
| [3d4397] | 1812 |   const char *tstr = ctime(&t);
 | 
|---|
| [5d30c1] | 1813 | #endif
 | 
|---|
 | 1814 |   if (!tstr) {
 | 
|---|
 | 1815 |     tstr = "UNKNOWN";
 | 
|---|
 | 1816 |   }
 | 
|---|
 | 1817 |   ExEnv::out0() << endl
 | 
|---|
 | 1818 |                << indent << scprintf("End Time: %s", tstr) << endl;
 | 
|---|
 | 1819 | }
 | 
|---|
 | 1820 | 
 | 
|---|
| [035791] | 1821 | // static values object
 | 
|---|
 | 1822 | OptionValues values;
 | 
|---|
 | 1823 | 
 | 
|---|
 | 1824 | #ifdef HAVE_JOBMARKET
 | 
|---|
 | 1825 | FragmentResult::ptr MPQCJob::Work()
 | 
|---|
 | 1826 | {
 | 
|---|
 | 1827 |   char mpqc[] = "mpqc" ;
 | 
|---|
 | 1828 |   char **argv = new char*[1];
 | 
|---|
 | 1829 |   argv[0] = &mpqc[0];
 | 
|---|
 | 1830 |   int argc = 1;
 | 
|---|
 | 1831 | //  init();
 | 
|---|
 | 1832 | //
 | 
|---|
 | 1833 | //  ExEnv::init(argc, argv);
 | 
|---|
 | 1834 | //
 | 
|---|
 | 1835 | //  // parse commandline options
 | 
|---|
 | 1836 | //  GetLongOpt options;
 | 
|---|
 | 1837 | //  int optind = ParseOptions(options, argc, argv);
 | 
|---|
 | 1838 | //  const char *output = 0;
 | 
|---|
 | 1839 | //  ostream *outstream = 0;
 | 
|---|
 | 1840 | //  ComputeOptions(options, output, outstream);
 | 
|---|
 | 1841 | //  OptionValues values;
 | 
|---|
 | 1842 | //  parseRemainderOptions(options, values, argc, argv);
 | 
|---|
 | 1843 | //
 | 
|---|
 | 1844 | //  // get the basename for output files
 | 
|---|
 | 1845 | //  char filename_template[] = "mpqc_temp_XXXXXX";
 | 
|---|
 | 1846 | //  output = mktemp(filename_template);
 | 
|---|
 | 1847 | //  setOutputBaseName(NULL, output);
 | 
|---|
 | 1848 | 
 | 
|---|
 | 1849 |   // now comes the actual work
 | 
|---|
 | 1850 |   int nfilebase = (int) inputfile.length();
 | 
|---|
 | 1851 |   char *in_char_array = new char[nfilebase + 1];
 | 
|---|
 | 1852 |   strncpy(in_char_array, inputfile.c_str(), nfilebase);
 | 
|---|
 | 1853 |   in_char_array[nfilebase] = '\0';
 | 
|---|
 | 1854 |   const char *input = 0;
 | 
|---|
 | 1855 |   const char *generic_input = 0;
 | 
|---|
| [4aba27] | 1856 |   Ref<MessageGrp> grp = MessageGrp::get_default_messagegrp();
 | 
|---|
| [16135f] | 1857 |   // create unique, temporary name and check whether it exists
 | 
|---|
 | 1858 |   const char *output = NULL;
 | 
|---|
 | 1859 |   std::ifstream test;
 | 
|---|
 | 1860 |   do {
 | 
|---|
| [cf3275] | 1861 |     char filename_template[] = "mpqc_temp_XXXXXX";
 | 
|---|
 | 1862 |     char filename_suffix[] = ".in\0";
 | 
|---|
 | 1863 |     char *tempfilename = (char *) malloc ( (strlen(filename_template)+strlen(filename_suffix))*(sizeof(char)));
 | 
|---|
 | 1864 |     strncpy(tempfilename, mktemp(filename_template), strlen(filename_template));
 | 
|---|
 | 1865 |     tempfilename[strlen(filename_template)] = '\0'; 
 | 
|---|
 | 1866 |     strncat(tempfilename, filename_suffix, strlen(filename_suffix));  
 | 
|---|
 | 1867 |     output = tempfilename;
 | 
|---|
| [16135f] | 1868 |     test.open(output);
 | 
|---|
 | 1869 |   } while (test.good());
 | 
|---|
| [0eb774e] | 1870 |   // put info how to sample the density into MPQCData
 | 
|---|
| [5ce17f] | 1871 |   MPQCData data(grid);
 | 
|---|
| [0eb774e] | 1872 | // now call work horse
 | 
|---|
| [4aba27] | 1873 |   mainFunction(grp, values, output, input, generic_input, in_char_array, argc, argv, data);
 | 
|---|
 | 1874 | //  delete[] in_char_array;
 | 
|---|
| [035791] | 1875 | 
 | 
|---|
 | 1876 | //  if (output != 0) {
 | 
|---|
 | 1877 | //    ExEnv::set_out(&cout);
 | 
|---|
 | 1878 | //    delete outstream;
 | 
|---|
 | 1879 | //  }
 | 
|---|
 | 1880 | //  delete[] argv;
 | 
|---|
 | 1881 | //
 | 
|---|
| [850bce] | 1882 |   // place into returnstream
 | 
|---|
 | 1883 |   std::stringstream returnstream;
 | 
|---|
 | 1884 |   boost::archive::text_oarchive oa(returnstream);
 | 
|---|
 | 1885 |   oa << data;
 | 
|---|
 | 1886 | 
 | 
|---|
 | 1887 |   FragmentResult::ptr s( new FragmentResult(getId(), returnstream.str()) );
 | 
|---|
 | 1888 |   return s;
 | 
|---|
| [035791] | 1889 | }
 | 
|---|
 | 1890 | #endif
 | 
|---|
 | 1891 | 
 | 
|---|
 | 1892 | // we need to explicitly instantiate the serialization functions as
 | 
|---|
 | 1893 | // its is only serialized through its base class FragmentJob
 | 
|---|
 | 1894 | BOOST_CLASS_EXPORT_IMPLEMENT(MPQCJob)
 | 
|---|
 | 1895 | 
 | 
|---|
| [ab755a] | 1896 | int
 | 
|---|
 | 1897 | try_main(int argc, char *argv[])
 | 
|---|
 | 1898 | {
 | 
|---|
 | 1899 |   init();
 | 
|---|
 | 1900 | 
 | 
|---|
 | 1901 |   ExEnv::init(argc, argv);
 | 
|---|
 | 1902 | 
 | 
|---|
 | 1903 |   // parse commandline options
 | 
|---|
 | 1904 |   GetLongOpt options;
 | 
|---|
 | 1905 |   int optind = ParseOptions(options, argc, argv);
 | 
|---|
 | 1906 |   const char *output = 0;
 | 
|---|
 | 1907 |   ostream *outstream = 0;
 | 
|---|
 | 1908 |   ComputeOptions(options, output, outstream);
 | 
|---|
 | 1909 |   parseRemainderOptions(options, values, argc, argv);
 | 
|---|
 | 1910 | 
 | 
|---|
 | 1911 |   // get input file names, either object-oriented or generic
 | 
|---|
 | 1912 |   const char *object_input = 0;
 | 
|---|
 | 1913 |   const char *generic_input = 0;
 | 
|---|
| [2fbba84] | 1914 |   getInputFileNames(object_input, generic_input, options, optind, argc, argv);
 | 
|---|
| [499cea] | 1915 |   const char *input = 0;
 | 
|---|
| [ab755a] | 1916 |   if (object_input) input = object_input;
 | 
|---|
 | 1917 |   if (generic_input) input = generic_input;
 | 
|---|
 | 1918 | 
 | 
|---|
| [4aba27] | 1919 |   // get the message group.  first try the commandline and environment
 | 
|---|
 | 1920 |   Ref<MessageGrp> grp;
 | 
|---|
 | 1921 |   getMessageGroup(grp, argc, argv);
 | 
|---|
| [ab755a] | 1922 | 
 | 
|---|
| [035791] | 1923 |   // check if we got option "-n"
 | 
|---|
 | 1924 |   int exitflag = 0;
 | 
|---|
 | 1925 | #ifdef HAVE_JOBMARKET
 | 
|---|
 | 1926 |   if (options.retrieve("n")) {
 | 
|---|
 | 1927 |     /// create new argc, argv and call by splitting with tokenizer
 | 
|---|
 | 1928 |     std::string networkstring(options.retrieve("n"));
 | 
|---|
 | 1929 |     typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
 | 
|---|
 | 1930 |     boost::char_separator<char> sep(" ");
 | 
|---|
 | 1931 |     tokenizer tok(networkstring, sep);
 | 
|---|
 | 1932 |     // simple count because tokenizer has now size()
 | 
|---|
 | 1933 |     int argc_network = 0;
 | 
|---|
 | 1934 |     for(tokenizer::iterator beg=tok.begin(); beg!=tok.end();++beg)
 | 
|---|
 | 1935 |       ++argc_network;
 | 
|---|
 | 1936 |     // argv[0] is program name
 | 
|---|
 | 1937 |     char **argv_network = new char*[argc_network+1];
 | 
|---|
 | 1938 |     argv_network[0] = new char[5];
 | 
|---|
 | 1939 |     strcpy(argv_network[0], "mpqc");
 | 
|---|
 | 1940 |     // then we place each token as a new argument
 | 
|---|
 | 1941 |     argc_network = 1;
 | 
|---|
 | 1942 |     for(tokenizer::iterator beg=tok.begin(); beg!=tok.end();++beg){
 | 
|---|
 | 1943 |       const size_t strlength = (*beg).length();
 | 
|---|
 | 1944 |       const char *strarray = beg->c_str();
 | 
|---|
 | 1945 |       //std::cout << "Token " << argc_network << " is " << strarray << ", length " << strlength << endl;
 | 
|---|
 | 1946 |       argv_network[argc_network] = new char[strlength+1];
 | 
|---|
 | 1947 |       strcpy(argv_network[argc_network], strarray);
 | 
|---|
 | 1948 |       argv_network[argc_network][strlength] = '\0';
 | 
|---|
 | 1949 |       for (size_t index = 0; index < strlength; ++index)
 | 
|---|
 | 1950 |         if (argv_network[argc_network][index] == '+')
 | 
|---|
 | 1951 |           argv_network[argc_network][index] = '-';
 | 
|---|
 | 1952 |       ++argc_network;
 | 
|---|
 | 1953 |     }
 | 
|---|
 | 1954 |     /// and start listening for MPQCJobs
 | 
|---|
 | 1955 |     exitflag = poolworker_main(argc_network, argv_network);
 | 
|---|
 | 1956 |     /// remove the artifical [argv,argv] again
 | 
|---|
 | 1957 |     for (int i=0;i<argc_network;++i)
 | 
|---|
 | 1958 |       delete[] argv_network[i];
 | 
|---|
 | 1959 |     delete[] argv_network;
 | 
|---|
 | 1960 |   } else
 | 
|---|
 | 1961 | #endif
 | 
|---|
 | 1962 |   {
 | 
|---|
 | 1963 |     // if not, work on the command line input
 | 
|---|
 | 1964 |     char *in_char_array = 0;
 | 
|---|
| [850bce] | 1965 | #ifdef HAVE_MPQCDATA
 | 
|---|
 | 1966 |     MPQCData data;
 | 
|---|
| [4aba27] | 1967 |     mainFunction(grp, values, output, input, generic_input, in_char_array, argc, argv, data);
 | 
|---|
| [850bce] | 1968 | #else
 | 
|---|
| [4aba27] | 1969 |     mainFunction(grp, values, output, input, generic_input, in_char_array, argc, argv);
 | 
|---|
| [850bce] | 1970 | #endif
 | 
|---|
| [035791] | 1971 |   }
 | 
|---|
| [ab755a] | 1972 | 
 | 
|---|
 | 1973 |   if (output != 0) {
 | 
|---|
 | 1974 |     ExEnv::set_out(&cout);
 | 
|---|
 | 1975 |     delete outstream;
 | 
|---|
 | 1976 |   }
 | 
|---|
 | 1977 | 
 | 
|---|
| [4aba27] | 1978 |   grp = 0;
 | 
|---|
 | 1979 |   final_clean_up();
 | 
|---|
 | 1980 | 
 | 
|---|
| [035791] | 1981 |   return exitflag;
 | 
|---|
| [ab755a] | 1982 | }
 | 
|---|
 | 1983 | 
 | 
|---|
 | 1984 | 
 | 
|---|
| [62dabe] | 1985 | double EvaluateDensity(SCVector3 &r, Ref<Integral> &intgrl, GaussianBasisSet::ValueData &vdat, Ref<Wavefunction> &wfn)
 | 
|---|
 | 1986 | {
 | 
|---|
 | 1987 |   ExEnv::out0() << "We get the following values at " << r << "." << endl;
 | 
|---|
 | 1988 |   int nbasis = wfn->basis()->nbasis();
 | 
|---|
 | 1989 |   double *b_val = new double[nbasis];
 | 
|---|
 | 1990 |   wfn->basis()->values(r, &vdat, b_val);
 | 
|---|
 | 1991 |   double sum=0.;
 | 
|---|
 | 1992 |   for (int i=0; i<nbasis; i++)
 | 
|---|
 | 1993 |     sum += b_val[i];
 | 
|---|
 | 1994 |   delete[] b_val;
 | 
|---|
 | 1995 |   return sum;
 | 
|---|
 | 1996 | }
 | 
|---|
 | 1997 | 
 | 
|---|
| [5d30c1] | 1998 | int
 | 
|---|
 | 1999 | main(int argc, char *argv[])
 | 
|---|
 | 2000 | {
 | 
|---|
| [0d2f18] | 2001 |   size_t exitflag = 0;
 | 
|---|
| [5d30c1] | 2002 |   try {
 | 
|---|
| [0d2f18] | 2003 |     exitflag = try_main(argc, argv);
 | 
|---|
| [5d30c1] | 2004 |   }
 | 
|---|
 | 2005 |   catch (SCException &e) {
 | 
|---|
 | 2006 |     cout << argv[0] << ": ERROR: SC EXCEPTION RAISED:" << endl
 | 
|---|
 | 2007 |          << e.what()
 | 
|---|
 | 2008 |          << endl;
 | 
|---|
 | 2009 |     clean_up();
 | 
|---|
 | 2010 |     throw;
 | 
|---|
 | 2011 |   }
 | 
|---|
 | 2012 |   catch (bad_alloc &e) {
 | 
|---|
 | 2013 |     cout << argv[0] << ": ERROR: MEMORY ALLOCATION FAILED:" << endl
 | 
|---|
 | 2014 |          << e.what()
 | 
|---|
 | 2015 |          << endl;
 | 
|---|
 | 2016 |     clean_up();
 | 
|---|
 | 2017 |     throw;
 | 
|---|
 | 2018 |   }
 | 
|---|
 | 2019 |   catch (exception &e) {
 | 
|---|
 | 2020 |     cout << argv[0] << ": ERROR: EXCEPTION RAISED:" << endl
 | 
|---|
 | 2021 |          << e.what()
 | 
|---|
 | 2022 |          << endl;
 | 
|---|
 | 2023 |     clean_up();
 | 
|---|
 | 2024 |     throw;
 | 
|---|
 | 2025 |   }
 | 
|---|
 | 2026 |   catch (...) {
 | 
|---|
 | 2027 |     cout << argv[0] << ": ERROR: UNKNOWN EXCEPTION RAISED" << endl;
 | 
|---|
 | 2028 |     clean_up();
 | 
|---|
 | 2029 |     throw;
 | 
|---|
 | 2030 |   }
 | 
|---|
| [0d2f18] | 2031 |   return exitflag;
 | 
|---|
| [5d30c1] | 2032 | }
 | 
|---|
 | 2033 | 
 | 
|---|
 | 2034 | /////////////////////////////////////////////////////////////////////////////
 | 
|---|
 | 2035 | 
 | 
|---|
 | 2036 | // Local Variables:
 | 
|---|
 | 2037 | // mode: c++
 | 
|---|
 | 2038 | // c-file-style: "ETS"
 | 
|---|
 | 2039 | // End:
 | 
|---|