Changeset fbf005 for ThirdParty/mpqc_open
- Timestamp:
- Mar 9, 2017, 9:43:23 AM (8 years ago)
- Branches:
- Action_Thermostats, Add_AtomRandomPerturbation, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_StructOpt_integration_tests, AutomationFragmentation_failures, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_ChronosMutex, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, GeometryObjects, Gui_displays_atomic_force_velocity, IndependentFragmentGrids_IntegrationTest, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, PartialCharges_OrthogonalSummation, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, RotateToPrincipalAxisSystem_UndoRedo, StoppableMakroAction, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, Ubuntu_1604_changes, stable
- Children:
- 7672284
- Parents:
- ba1152
- git-author:
- Frederik Heber <heber@…> (03/08/17 08:11:59)
- git-committer:
- Frederik Heber <heber@…> (03/09/17 09:43:23)
- Location:
- ThirdParty/mpqc_open/src/bin/mpqc
- Files:
-
- 4 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
ThirdParty/mpqc_open/src/bin/mpqc/Makefile.am
rba1152 rfbf005 1 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src/lib 1 AM_CPPFLAGS = \ 2 -I$(top_srcdir)/include -I$(top_srcdir)/src/lib \ 3 -DHAVE_JOBMARKET -I$(top_srcdir)/../JobMarket/src -I$(top_builddir)/../JobMarket -I$(top_srcdir)/../../src -I$(top_srcdir)/../LinearAlgebra/src -I$(top_srcdir)/../CodePatterns/src $(BOOST_SYSTEM_CFLAGS) \ 4 -DHAVE_MPQCDATA -I$(top_builddir)/../../src 2 5 3 6 bin_PROGRAMS = molecuilder_mpqc 4 7 5 noinst_LTLIBRARIES = libmpqc.la 8 lib_LTLIBRARIES = \ 9 libmolecuilder_mpqc.la 6 10 7 libmpqc_la_SOURCES = \ 11 noinst_LTLIBRARIES = \ 12 libmolecuilder_mpqc_extract_dummy.la 13 14 LIBMPQCSOURCES = \ 15 mpqc.cc \ 8 16 mpqcin.cc \ 17 parse.cc \ 18 scan.cc 19 20 LIBMPQCHEADERS = \ 21 mpqc.h \ 9 22 mpqcin.h \ 10 parse.cc \11 23 parse.h \ 12 scan.cc \13 24 scdirlist.h 14 25 26 libmolecuilder_mpqc_extract_dummy_la_SOURCES = \ 27 mpqc_extract_dummy.cc \ 28 mpqc_extract.h 29 30 libmolecuilder_mpqc_la_includedir = $(includedir)/molecuilder_mpqc/ 31 libmolecuilder_mpqc_la_CPPFLAGS = $(AM_CPPFLAGS) 32 libmolecuilder_mpqc_la_LDFLAGS = $(AM_LDFLAGS) 33 34 libmolecuilder_mpqc_la_LIBADD = \ 35 ../../lib/libSCmbpt.la ../../lib/libSCscf.la ../../lib/libSCdft.la ../../lib/libSCwfn.la ../../lib/libSCpsi.la ../../lib/libSCsolvent.la ../../lib/libSCintv3.la ../../lib/libSCbasis.la ../../lib/libSCoint3.la ../../lib/libSCmolecule.la ../../lib/libSCisosurf.la ../../lib/libSCoptimize.la ../../lib/libSCsymmetry.la ../../lib/libSCscmat.la ../../lib/libSCrender.la ../../lib/libSCgroup.la ../../lib/libSCmisc.la ../../lib/libSCstate.la ../../lib/libSCkeyval.la ../../lib/libSCclass.la ../../lib/libSCcontainer.la ../../lib/libSCref.la ../../lib/libSCoptions.la 36 37 nobase_libmolecuilder_mpqc_la_include_HEADERS = ${LIBMPQCHEADERS} 38 39 ## Define the source file list for the "libexample-@MOLECUILDER_API_VERSION@.la" 40 ## target. Note that @MOLECUILDER_API_VERSION@ is not interpreted by Automake and 41 ## will therefore be treated as if it were literally part of the target name, 42 ## and the variable name derived from that. 43 ## The file extension .cc is recognized by Automake, and makes it produce 44 ## rules which invoke the C++ compiler to produce a libtool object file (.lo) 45 ## from each source file. Note that it is not necessary to list header files 46 ## which are already listed elsewhere in a _HEADERS variable assignment. 47 libmolecuilder_mpqc_la_SOURCES = ${LIBMPQCSOURCES} 48 49 ## Instruct libtool to include ABI version information in the generated shared 50 ## library file (.so). The library ABI version is defined in configure.ac, so 51 ## that all version information is kept in one place. 52 libmolecuilder_mpqc_la_LDFLAGS += -version-info $(MPQC_SO_VERSION) 53 54 ## The generated configuration header is installed in its own subdirectory of 55 ## $(libdir). The reason for this is that the configuration information put 56 ## into this header file describes the target platform the installed library 57 ## has been built for. Thus the file must not be installed into a location 58 ## intended for architecture-independent files, as defined by the Filesystem 59 ## Hierarchy Standard (FHS). 60 ## The nodist_ prefix instructs Automake to not generate rules for including 61 ## the listed files in the distribution on 'make dist'. Files that are listed 62 ## in _HEADERS variables are normally included in the distribution, but the 63 ## configuration header file is generated at configure time and should not be 64 ## shipped with the source tarball. 65 libmolecuilder_mpqc_la_libincludedir = $(libdir)/molecuilder_mpqc/include 66 nodist_libmolecuilder_mpqc_la_libinclude_HEADERS = $(top_builddir)/src/lib/scconfig.h 67 68 ## Install the generated pkg-config file (.pc) into the expected location for 69 ## architecture-dependent package configuration information. Occasionally, 70 ## pkg-config files are also used for architecture-independent data packages, 71 ## in which case the correct install location would be $(datadir)/pkgconfig. 72 #pkgconfigdir = $(libdir)/pkgconfig 73 #pkgconfig_DATA = $(top_builddir)/molecuilder_mpqc.pc 74 15 75 molecuilder_mpqc_SOURCES = \ 16 mpqc .cc76 mpqc_main.cc 17 77 18 molecuilder_mpqc_CPPFLAGS = \19 $(AM_CPPFLAGS) \20 -DHAVE_JOBMARKET -I$(top_srcdir)/../JobMarket/src -I$(top_builddir)/../JobMarket -I$(top_srcdir)/../../src -I$(top_srcdir)/../LinearAlgebra/src $(BOOST_SYSTEM_CFLAGS) \21 -DHAVE_MPQCDATA -I$(top_builddir)/../../src22 23 molecuilder_mpqc_LDFLAGS = \24 $(AM_LDFLAGS) \25 -L$(top_builddir)/../JobMarket/src/JobMarket/.libs -Wl,-rpath,$(top_builddir)/../JobMarket/src/JobMarket/.libs \26 -L$(top_builddir)/../../src/.libs -Wl,-rpath,$(top_builddir)/../../src/.libs \27 $(BOOST_SYSTEM_LDFLAGS)28 78 molecuilder_mpqc_LDADD = \ 29 libmpqc.la ../../lib/libSCmbpt.la ../../lib/libSCscf.la ../../lib/libSCdft.la ../../lib/libSCwfn.la ../../lib/libSCpsi.la ../../lib/libSCsolvent.la ../../lib/libSCintv3.la ../../lib/libSCbasis.la ../../lib/libSCoint3.la ../../lib/libSCmolecule.la ../../lib/libSCisosurf.la ../../lib/libSCoptimize.la ../../lib/libSCsymmetry.la ../../lib/libSCscmat.la ../../lib/libSCrender.la ../../lib/libSCgroup.la ../../lib/libSCmisc.la ../../lib/libSCstate.la ../../lib/libSCkeyval.la ../../lib/libSCclass.la ../../lib/libSCcontainer.la ../../lib/libSCref.la ../../lib/libSCoptions.la \ 30 -lJobMarketPoolWorker -lJobMarket \ 31 -lMolecuilderJobs -lMolecuilderFragmentationSummation \ 32 -lboost_serialization 79 libmolecuilder_mpqc.la libmolecuilder_mpqc_extract_dummy.la 33 80 if COND_LIBINT 34 81 molecuilder_mpqc_LDADD += -lint -
ThirdParty/mpqc_open/src/bin/mpqc/mpqc.cc
rba1152 rfbf005 123 123 #endif 124 124 125 #ifdef HAVE_JOBMARKET126 // include headers that implement a archive in simple text format127 // otherwise BOOST_CLASS_EXPORT_IMPLEMENT has no effect128 #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 136 #include "chemistry/qc/scf/scfops.h"137 138 #ifdef HAVE_MPQCDATA139 #include "Jobs/MPQCJob.hpp"140 #include "Fragmentation/Summation/Containers/MPQCData.hpp"141 142 #include <chemistry/qc/basis/obint.h>143 #include <chemistry/qc/basis/symmint.h>144 #endif145 146 #include <algorithm>147 #include <stdlib.h>148 #endif149 150 125 using namespace std; 151 126 using namespace sc; 152 127 153 128 #include "mpqcin.h" 129 #include "mpqc.h" 130 #include "mpqc_extract.h" 154 131 155 132 ////////////////////////////////////////////////////////////////////////// … … 178 155 } 179 156 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 } 157 namespace detail { 158 159 void 160 clean_up(void) 161 { 162 ::MemoryGrp::set_default_memorygrp(0); 163 ::ThreadGrp::set_default_threadgrp(0); 164 ::SCMatrixKit::set_default_matrixkit(0); 165 ::Integral::set_default_integral(0); 166 ::RegionTimer::set_default_regiontimer(0); 167 } 168 169 } /* namespace detail */ 189 170 190 171 static void … … 335 316 } 336 317 337 /** Temporary structure for storing information from command-line338 *339 * This structure has been introduced to gather the various calls to GetLongOpts340 * 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 become342 * 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"350 string executablename;351 352 #ifdef HAVE_CHEMISTRY_CCA353 string cca_load; // option "cca-path"354 string cc_path; // option "cca-load"355 #endif356 };357 358 318 /** Parse remainder options not treated by ComputeOptions() into temporary storage. 359 319 * … … 364 324 void parseRemainderOptions( 365 325 GetLongOpt &options, 366 structOptionValues &values,326 detail::OptionValues &values, 367 327 int argc, 368 328 char **argv) … … 655 615 /** Parse the input configuration from char array into keyvalue container. 656 616 * 657 * \param parsedkv key value container to f oll617 * \param parsedkv key value container to fill 658 618 * \param values temporary options value structure 659 619 * \param in_char_array char array with input file … … 663 623 void parseIntoKeyValue( 664 624 Ref<ParsedKeyVal> &parsedkv, 665 structOptionValues &values,625 detail::OptionValues &values, 666 626 char *&in_char_array, 667 627 int use_simple_input) … … 699 659 Ref<MessageGrp> &grp, 700 660 Ref<ParsedKeyVal> &parsedkv, 701 structOptionValues &values,661 detail::OptionValues &values, 702 662 const char *&input, 703 663 const char *&generic_input, … … 804 764 void prepareCCA( 805 765 Ref<KeyVal> &keyval, 806 structOptionValues &values766 detail::OptionValues &values 807 767 ) 808 768 { … … 851 811 Ref<MessageGrp> &grp, 852 812 Ref<Debugger> &debugger, 853 structOptionValues &values)813 detail::OptionValues &values) 854 814 { 855 815 debugger << keyval->describedclassvalue("debug"); … … 971 931 int checkBasisSetLimit( 972 932 Ref<MolecularEnergy> &mole, 973 structOptionValues &values933 detail::OptionValues &values 974 934 ) 975 935 { … … 1182 1142 } 1183 1143 1184 static int getCoreElectrons(const int z)1185 {1186 int n=0;1187 if (z > 2) n += 2;1188 if (z > 10) n += 8;1189 if (z > 18) n += 8;1190 if (z > 30) n += 10;1191 if (z > 36) n += 8;1192 if (z > 48) n += 10;1193 if (z > 54) n += 8;1194 return n;1195 }1196 1197 1144 void init() 1198 1145 { … … 1200 1147 1201 1148 int i; 1202 atexit( clean_up);1149 atexit(detail::clean_up); 1203 1150 1204 1151 #ifdef HAVE_FEENABLEEXCEPT … … 1233 1180 } 1234 1181 1235 /** Finds the region index to a given timer region name.1236 *1237 * @param nregion number of regions1238 * @param region_names array with name of each region1239 * @param name name of desired region1240 * @return index of desired region in array1241 */1242 int findTimerRegion(const int &nregion, const char **®ion_names, const char *name)1243 {1244 size_t region=0;1245 for (;region<nregion;++region) {1246 //std::cout << "Comparing " << region_names[region] << " and " << name << "." << std::endl;1247 if (strcmp(region_names[region], name) == 0)1248 break;1249 }1250 if (region == nregion)1251 region = 0;1252 return region;1253 }1254 1255 1182 /** Performs the main work to calculate the ground state energies, gradients, etc. 1256 1183 * 1257 * @param grp message group 1258 * @param values temporary value storage for parsed command-line 1259 * @param input input file name 1260 * @param generic_input generic input file name 1261 * @param in_char_array either NULL or contains char array with read input 1184 * @param _initvalues struct with all state variables 1262 1185 * @param argc argument count 1263 1186 * @param argv argument array 1264 */ 1265 void mainFunction( 1266 Ref<MessageGrp> grp, 1267 struct OptionValues &values, 1268 const char *&output, 1269 const char *&input, 1270 const char *&generic_input, 1271 char *&in_char_array, 1187 * @param data void ptr to extract structure 1188 */ 1189 void mpqc::mainFunction( 1190 mpqc::InitValues &_initvalues, 1272 1191 int argc, 1273 char **argv 1274 #ifdef HAVE_MPQCDATA 1275 , MPQCData &data 1276 #endif 1192 char **argv, 1193 void *data 1277 1194 ) 1278 1195 { 1279 1196 // get the basename for output files 1280 setOutputBaseName( input,output);1197 setOutputBaseName(_initvalues.input, _initvalues.output); 1281 1198 1282 1199 // parse input into keyvalue container 1283 1200 Ref<ParsedKeyVal> parsedkv; 1284 1201 int use_simple_input = 0; // default is object-oriented if in_char_array is given 1285 if (!in_char_array) // obtain from file 1286 parseInputfile(grp, parsedkv, values, input, generic_input, in_char_array, use_simple_input); 1287 parseIntoKeyValue(parsedkv, values, in_char_array, use_simple_input); 1288 delete[] in_char_array; 1202 if (!_initvalues.in_char_array) // obtain from file 1203 parseInputfile( 1204 _initvalues.grp, 1205 parsedkv, 1206 _initvalues.values, 1207 _initvalues.input, 1208 _initvalues.generic_input, 1209 _initvalues.in_char_array, 1210 use_simple_input); 1211 parseIntoKeyValue( 1212 parsedkv, 1213 _initvalues.values, 1214 _initvalues.in_char_array, 1215 use_simple_input); 1216 // delete[] in_char_array; 1289 1217 1290 1218 // prefix parsed values wit "mpqc" 1291 if ( values.keyvalue) parsedkv->verbose(1);1219 if (_initvalues.values.keyvalue) parsedkv->verbose(1); 1292 1220 Ref<KeyVal> keyval = new PrefixKeyVal(parsedkv.pointer(),"mpqc"); 1293 1221 1294 1222 // set up output classes 1295 setupSCFormIO( grp);1223 setupSCFormIO(_initvalues.grp); 1296 1224 1297 1225 // initialize timing for mpqc 1298 1226 Ref<RegionTimer> tim; 1299 initTimings( grp, keyval, tim);1227 initTimings(_initvalues.grp, keyval, tim); 1300 1228 1301 1229 // announce ourselves … … 1311 1239 1312 1240 ExEnv::out0() << indent 1313 << "Using " << grp->class_name()1314 << " for message passing (number of nodes = " << grp->n() << ")." << endl1241 << "Using " << _initvalues.grp->class_name() 1242 << " for message passing (number of nodes = " << _initvalues.grp->n() << ")." << endl 1315 1243 << indent 1316 1244 << "Using " << thread->class_name() … … 1320 1248 << " for distributed shared memory." << endl 1321 1249 << indent 1322 << "Total number of processors = " << grp->n() * thread->nthread() << endl;1250 << "Total number of processors = " << _initvalues.grp->n() * thread->nthread() << endl; 1323 1251 1324 1252 // prepare CCA if available 1325 prepareCCA(keyval, values);1253 prepareCCA(keyval, _initvalues.values); 1326 1254 1327 1255 // now set up the debugger 1328 1256 Ref<Debugger> debugger; 1329 setupDebugger(keyval, grp, debugger,values);1257 setupDebugger(keyval, _initvalues.grp, debugger, _initvalues.values); 1330 1258 1331 1259 // now check to see what matrix kit to use … … 1370 1298 1371 1299 // read in restart file if we do restart 1372 performRestart(keyval, grp, opt, mole, restartfile);1300 performRestart(keyval, _initvalues.grp, opt, mole, restartfile); 1373 1301 1374 1302 // setup molecule checkpoint file 1375 setMolecularCheckpointFile(keyval, grp, mole, mole_ckpt_file);1303 setMolecularCheckpointFile(keyval, _initvalues.grp, mole, mole_ckpt_file); 1376 1304 delete[] mole_ckpt_file; 1377 1305 … … 1379 1307 if (checkpoint && opt.nonnull()) { 1380 1308 opt->set_checkpoint(); 1381 if ( grp->me() == 0) opt->set_checkpoint_file(ckptfile);1309 if (_initvalues.grp->me() == 0) opt->set_checkpoint_file(ckptfile); 1382 1310 else opt->set_checkpoint_file(devnull); 1383 1311 } … … 1390 1318 1391 1319 // check basis set limit 1392 const int check = checkBasisSetLimit(mole, values);1320 const int check = checkBasisSetLimit(mole, _initvalues.values); 1393 1321 if (check) { 1394 1322 ExEnv::out0() << endl << indent … … 1426 1354 // requiring optimized geometries, etc. 1427 1355 if (renderer.null()) { 1428 if (parsedkv.nonnull()) print_unseen(parsedkv, input);1356 if (parsedkv.nonnull()) print_unseen(parsedkv, _initvalues.input); 1429 1357 keyval = 0; 1430 1358 parsedkv = 0; … … 1465 1393 1466 1394 // save this before doing the frequency stuff since that obsoletes the 1467 saveState(wfn_file, savestate, opt, grp, mole, molname, ckptfile);1395 saveState(wfn_file, savestate, opt, _initvalues.grp, mole, molname, ckptfile); 1468 1396 1469 1397 // Frequency calculation. … … 1473 1401 1474 1402 if (renderer.nonnull()) { 1475 renderObjects(renderer, keyval, tim, grp);1403 renderObjects(renderer, keyval, tim, _initvalues.grp); 1476 1404 1477 1405 Ref<MolFreqAnimate> molfreqanim; … … 1489 1417 mole->print(ExEnv::out0()); 1490 1418 1491 saveToPdb(do_pdb, grp, mole, molname);1419 saveToPdb(do_pdb, _initvalues.grp, mole, molname); 1492 1420 1493 1421 } … … 1497 1425 << endl; 1498 1426 } 1499 if (parsedkv.nonnull()) print_unseen(parsedkv, input);1427 if (parsedkv.nonnull()) print_unseen(parsedkv, _initvalues.input); 1500 1428 1501 1429 // here, we may gather the results 1502 1430 // we start to fill the MPQC_Data object 1503 if (tim.nonnull()) tim->enter("gather"); 1504 { 1505 Ref<Wavefunction> wfn; 1506 wfn << mole; 1507 // ExEnv::out0() << "The number of atomic orbitals: " << wfn->ao_dimension()->n() << endl; 1508 // ExEnv::out0() << "The AO density matrix is "; 1509 // wfn->ao_density()->print(ExEnv::out0()); 1510 // ExEnv::out0() << "The natural density matrix is "; 1511 // wfn->natural_density()->print(ExEnv::out0()); 1512 // ExEnv::out0() << "The Gaussian basis is " << wfn->basis()->name() << endl; 1513 // ExEnv::out0() << "The Gaussians sit at the following centers: " << endl; 1514 // for (int nr = 0; nr< wfn->basis()->ncenter(); ++nr) { 1515 // ExEnv::out0() << nr << " basis function has its center at "; 1516 // for (int i=0; i < 3; ++i) 1517 // ExEnv::out0() << wfn->basis()->r(nr,i) << "\t"; 1518 // ExEnv::out0() << endl; 1519 // } 1520 // store accuracies 1521 data.accuracy = mole->value_result().actual_accuracy(); 1522 data.desired_accuracy = mole->value_result().desired_accuracy(); 1523 // print the energy 1524 data.energies.total = wfn->energy(); 1525 data.energies.nuclear_repulsion = wfn->nuclear_repulsion_energy(); 1526 { 1527 CLHF *clhf = dynamic_cast<CLHF*>(wfn.pointer()); 1528 if (clhf != NULL) { 1529 double ex, ec; 1530 clhf->two_body_energy(ec, ex); 1531 data.energies.electron_coulomb = ec; 1532 data.energies.electron_exchange = ex; 1533 clhf = NULL; 1534 } else { 1535 ExEnv::out0() << "INFO: There is no direct CLHF information available." << endl; 1536 data.energies.electron_coulomb = 0.; 1537 data.energies.electron_exchange = 0.; 1538 } 1539 } 1540 SCF *scf = NULL; 1541 { 1542 MBPT2 *mbpt2 = dynamic_cast<MBPT2*>(wfn.pointer()); 1543 if (mbpt2 != NULL) { 1544 data.energies.correlation = mbpt2->corr_energy(); 1545 scf = mbpt2->ref().pointer(); 1546 CLHF *clhf = dynamic_cast<CLHF*>(scf); 1547 if (clhf != NULL) { 1548 double ex, ec; 1549 clhf->two_body_energy(ec, ex); 1550 data.energies.electron_coulomb = ec; 1551 data.energies.electron_exchange = ex; 1552 clhf = NULL; 1553 } else { 1554 ExEnv::out0() << "INFO: There is no reference CLHF information available either." << endl; 1555 data.energies.electron_coulomb = 0.; 1556 data.energies.electron_exchange = 0.; 1557 } 1558 mbpt2 = 0; 1559 } else { 1560 ExEnv::out0() << "INFO: There is no MBPT2 information available." << endl; 1561 data.energies.correlation = 0.; 1562 scf = dynamic_cast<SCF*>(wfn.pointer()); 1563 if (scf == NULL) 1564 abort(); 1565 } 1566 } 1567 { 1568 // taken from clscf.cc: CLSCF::scf_energy() (but see also Szabo/Ostlund) 1569 1570 RefSymmSCMatrix t = scf->overlap(); 1571 RefSymmSCMatrix cl_dens_ = scf->ao_density(); 1572 1573 SCFEnergy *eop = new SCFEnergy; 1574 eop->reference(); 1575 if (t.dim()->equiv(cl_dens_.dim())) { 1576 Ref<SCElementOp2> op = eop; 1577 t.element_op(op,cl_dens_); 1578 op=0; 1579 } 1580 eop->dereference(); 1581 1582 data.energies.overlap = eop->result(); 1583 1584 delete eop; 1585 t = 0; 1586 cl_dens_ = 0; 1587 } 1588 { 1589 // taken from Wavefunction::core_hamiltonian() 1590 RefSymmSCMatrix hao(scf->basis()->basisdim(), scf->basis()->matrixkit()); 1591 hao.assign(0.0); 1592 Ref<PetiteList> pl = scf->integral()->petite_list(); 1593 Ref<SCElementOp> hc = 1594 new OneBodyIntOp(new SymmOneBodyIntIter(scf->integral()->kinetic(), pl)); 1595 hao.element_op(hc); 1596 hc=0; 1597 1598 RefSymmSCMatrix h(scf->so_dimension(), scf->basis_matrixkit()); 1599 pl->symmetrize(hao,h); 1600 1601 // taken from clscf.cc: CLSCF::scf_energy() (but see also Szabo/Ostlund) 1602 RefSymmSCMatrix cl_dens_ = scf->ao_density(); 1603 1604 SCFEnergy *eop = new SCFEnergy; 1605 eop->reference(); 1606 if (h.dim()->equiv(cl_dens_.dim())) { 1607 Ref<SCElementOp2> op = eop; 1608 h.element_op(op,cl_dens_); 1609 op=0; 1610 } 1611 eop->dereference(); 1612 1613 data.energies.kinetic = 2.*eop->result(); 1614 1615 delete eop; 1616 hao = 0; 1617 h = 0; 1618 cl_dens_ = 0; 1619 } 1620 { 1621 // set to potential energy between nuclei and electron charge distribution 1622 RefSymmSCMatrix hao(scf->basis()->basisdim(), scf->basis()->matrixkit()); 1623 hao.assign(0.0); 1624 Ref<PetiteList> pl = scf->integral()->petite_list(); 1625 Ref<SCElementOp> hc = 1626 new OneBodyIntOp(new SymmOneBodyIntIter(scf->integral()->nuclear(), pl)); 1627 hao.element_op(hc); 1628 hc=0; 1629 1630 RefSymmSCMatrix h(scf->so_dimension(), scf->basis_matrixkit()); 1631 pl->symmetrize(hao,h); 1632 1633 // taken from clscf.cc: CLSCF::scf_energy() (but see also Szabo/Ostlund) 1634 RefSymmSCMatrix cl_dens_ = scf->ao_density(); 1635 1636 SCFEnergy *eop = new SCFEnergy; 1637 eop->reference(); 1638 if (h.dim()->equiv(cl_dens_.dim())) { 1639 Ref<SCElementOp2> op = eop; 1640 h.element_op(op,cl_dens_); 1641 op=0; 1642 } 1643 eop->dereference(); 1644 1645 data.energies.hcore = 2.*eop->result(); 1646 1647 delete eop; 1648 hao = 0; 1649 h = 0; 1650 cl_dens_ = 0; 1651 } 1652 ExEnv::out0() << "total is " << data.energies.total << endl; 1653 ExEnv::out0() << "nuclear_repulsion is " << data.energies.nuclear_repulsion << endl; 1654 ExEnv::out0() << "electron_coulomb is " << data.energies.electron_coulomb << endl; 1655 ExEnv::out0() << "electron_exchange is " << data.energies.electron_exchange << endl; 1656 ExEnv::out0() << "correlation is " << data.energies.correlation << endl; 1657 ExEnv::out0() << "overlap is " << data.energies.overlap << endl; 1658 ExEnv::out0() << "kinetic is " << data.energies.kinetic << endl; 1659 ExEnv::out0() << "hcore is " << data.energies.hcore << endl; 1660 ExEnv::out0() << "sum is " << 1661 data.energies.nuclear_repulsion 1662 + data.energies.electron_coulomb 1663 + data.energies.electron_exchange 1664 + data.energies.correlation 1665 + data.energies.kinetic 1666 + data.energies.hcore 1667 << endl; 1668 1669 ExEnv::out0() << endl << indent 1670 << scprintf("Value of the MolecularEnergy: %15.10f", 1671 mole->energy()) 1672 << endl; 1673 // print the gradient 1674 RefSCVector grad; 1675 if (mole->gradient_result().computed()) { 1676 grad = mole->gradient_result().result_noupdate(); 1677 } 1678 // gradient calculation needs to be activated in the configuration 1679 // some methods such as open shell MBPT2 do not allow for gradient calc. 1680 // else { 1681 // grad = mole->gradient(); 1682 // } 1683 if (grad.nonnull()) { 1684 data.forces.resize(grad.dim()/3); 1685 for (int j=0;j<grad.dim()/3; ++j) { 1686 data.forces[j].resize(3, 0.); 1687 } 1688 ExEnv::out0() << "Gradient of the MolecularEnergy:" << std::endl; 1689 for (int j=0;j<grad.dim()/3; ++j) { 1690 ExEnv::out0() << "\t"; 1691 for (int i=0; i< 3; ++i) { 1692 data.forces[j][i] = grad[3*j+i]; 1693 ExEnv::out0() << grad[3*j+i] << "\t"; 1694 } 1695 ExEnv::out0() << endl; 1696 } 1697 } else { 1698 ExEnv::out0() << "INFO: There is no gradient information available." << endl; 1699 } 1700 grad = NULL; 1701 1702 { 1703 // eigenvalues (this only works if we have a OneBodyWavefunction, i.e. SCF procedure) 1704 // eigenvalues seem to be invalid for unrestricted SCF calculation 1705 // (see UnrestrictedSCF::eigenvalues() implementation) 1706 UnrestrictedSCF *uscf = dynamic_cast<UnrestrictedSCF*>(wfn.pointer()); 1707 if ((scf != NULL) && (uscf == NULL)) { 1708 const double scfernergy = scf->energy(); 1709 RefDiagSCMatrix evals = scf->eigenvalues(); 1710 1711 ExEnv::out0() << "Eigenvalues:" << endl; 1712 for(int i=0;i<wfn->oso_dimension(); ++i) { 1713 data.energies.eigenvalues.push_back(evals(i)); 1714 ExEnv::out0() << i << "th eigenvalue is " << evals(i) << endl; 1715 } 1716 } else { 1717 ExEnv::out0() << "INFO: There is no eigenvalue information available." << endl; 1718 } 1719 } 1720 // we do sample the density only on request 1721 { 1722 // fill positions and charges (NO LONGER converting from bohr radii to angstroem) 1723 const double AtomicLengthToAngstroem = 1.;//0.52917721; 1724 data.positions.reserve(wfn->molecule()->natom()); 1725 data.atomicnumbers.reserve(wfn->molecule()->natom()); 1726 data.charges.reserve(wfn->molecule()->natom()); 1727 for (int iatom=0;iatom < wfn->molecule()->natom(); ++iatom) { 1728 data.atomicnumbers.push_back(wfn->molecule()->Z(iatom)); 1729 double charge = wfn->molecule()->Z(iatom); 1730 if (data.DoValenceOnly == MPQCData::DoSampleValenceOnly) 1731 charge -= getCoreElectrons((int)charge); 1732 data.charges.push_back(charge); 1733 std::vector<double> pos(3, 0.); 1734 for (int j=0;j<3;++j) 1735 pos[j] = wfn->molecule()->r(iatom, j)*AtomicLengthToAngstroem; 1736 data.positions.push_back(pos); 1737 } 1738 ExEnv::out0() << "We have " 1739 << data.positions.size() << " positions and " 1740 << data.charges.size() << " charges." << endl; 1741 } 1742 if (data.DoLongrange) { 1743 if (data.sampled_grid.level != 0) 1744 { 1745 // we now need to sample the density on the grid 1746 // 1. get max and min over all basis function positions 1747 assert( scf->basis()->ncenter() > 0 ); 1748 SCVector3 bmin( scf->basis()->r(0,0), scf->basis()->r(0,1), scf->basis()->r(0,2) ); 1749 SCVector3 bmax( scf->basis()->r(0,0), scf->basis()->r(0,1), scf->basis()->r(0,2) ); 1750 for (int nr = 1; nr< scf->basis()->ncenter(); ++nr) { 1751 for (int i=0; i < 3; ++i) { 1752 if (scf->basis()->r(nr,i) < bmin(i)) 1753 bmin(i) = scf->basis()->r(nr,i); 1754 if (scf->basis()->r(nr,i) > bmax(i)) 1755 bmax(i) = scf->basis()->r(nr,i); 1756 } 1757 } 1758 ExEnv::out0() << "Basis min is at " << bmin << " and max is at " << bmax << endl; 1759 1760 // 2. choose an appropriately large grid 1761 // we have to pay attention to capture the right amount of the exponential decay 1762 // and also to have a power of two size of the grid at best 1763 SCVector3 boundaryV(5.); // boundary extent around compact domain containing basis functions 1764 bmin -= boundaryV; 1765 bmax += boundaryV; 1766 for (size_t i=0;i<3;++i) { 1767 if (bmin(i) < data.sampled_grid.begin[i]) 1768 bmin(i) = data.sampled_grid.begin[i]; 1769 if (bmax(i) > data.sampled_grid.end[i]) 1770 bmax(i) = data.sampled_grid.end[i]; 1771 } 1772 // set the non-zero window of the sampled_grid 1773 data.sampled_grid.setWindow(bmin.data(), bmax.data()); 1774 1775 // for the moment we always generate a grid of full size 1776 // (NO LONGER converting grid dimensions from angstroem to bohr radii) 1777 const double AtomicLengthToAngstroem = 1.;//0.52917721; 1778 SCVector3 min; 1779 SCVector3 max; 1780 SCVector3 delta; 1781 size_t samplepoints[3]; 1782 // due to periodic boundary conditions, we don't need gridpoints-1 here 1783 // TODO: in case of open boundary conditions, we need data on the right 1784 // hand side boundary as well 1785 const int gridpoints = data.sampled_grid.getGridPointsPerAxis(); 1786 for (size_t i=0;i<3;++i) { 1787 min(i) = data.sampled_grid.begin_window[i]/AtomicLengthToAngstroem; 1788 max(i) = data.sampled_grid.end_window[i]/AtomicLengthToAngstroem; 1789 delta(i) = data.sampled_grid.getDeltaPerAxis(i)/AtomicLengthToAngstroem; 1790 samplepoints[i] = data.sampled_grid.getWindowGridPointsPerAxis(i); 1791 } 1792 ExEnv::out0() << "Grid starts at " << min 1793 << " and ends at " << max 1794 << " with a delta of " << delta 1795 << " to get " 1796 << samplepoints[0] << "," 1797 << samplepoints[1] << "," 1798 << samplepoints[2] << " samplepoints." 1799 << endl; 1800 assert( data.sampled_grid.sampled_grid.size() == samplepoints[0]*samplepoints[1]*samplepoints[2]); 1801 1802 // 3. sample the atomic density 1803 const double element_volume_conversion = 1804 1./AtomicLengthToAngstroem/AtomicLengthToAngstroem/AtomicLengthToAngstroem; 1805 SCVector3 r = min; 1806 1807 std::set<int> valence_indices; 1808 RefDiagSCMatrix evals = scf->eigenvalues(); 1809 if (data.DoValenceOnly == MPQCData::DoSampleValenceOnly) { 1810 // find valence orbitals 1811 // std::cout << "All Eigenvalues:" << std::endl; 1812 // for(int i=0;i<wfn->oso_dimension(); ++i) 1813 // std::cout << i << "th eigenvalue is " << evals(i) << std::endl; 1814 int n_electrons = scf->nelectron(); 1815 int n_core_electrons = wfn->molecule()->n_core_electrons(); 1816 std::set<double> evals_sorted; 1817 { 1818 int i=0; 1819 double first_positive_ev = std::numeric_limits<double>::max(); 1820 for(i=0;i<wfn->oso_dimension(); ++i) { 1821 if (evals(i) < 0.) 1822 evals_sorted.insert(evals(i)); 1823 else 1824 first_positive_ev = std::min(first_positive_ev, (double)evals(i)); 1825 } 1826 // add the first positive for the distance 1827 evals_sorted.insert(first_positive_ev); 1828 } 1829 std::set<double> evals_distances; 1830 std::set<double>::const_iterator advancer = evals_sorted.begin(); 1831 std::set<double>::const_iterator iter = advancer++; 1832 for(;advancer != evals_sorted.end(); ++advancer,++iter) 1833 evals_distances.insert((*advancer)-(*iter)); 1834 const double largest_distance = *(evals_distances.rbegin()); 1835 ExEnv::out0() << "Largest distance between EV is " << largest_distance << std::endl; 1836 advancer = evals_sorted.begin(); 1837 iter = advancer++; 1838 for(;advancer != evals_sorted.begin(); ++advancer,++iter) 1839 if (fabs(fabs((*advancer)-(*iter)) - largest_distance) < 1e-10) 1840 break; 1841 assert( advancer != evals_sorted.begin() ); 1842 const double last_core_ev = (*iter); 1843 ExEnv::out0() << "Last core EV might be " << last_core_ev << std::endl; 1844 ExEnv::out0() << "First valence index is " << n_core_electrons/2 << std::endl; 1845 for(int i=n_core_electrons/2;i<wfn->oso_dimension(); ++i) 1846 if (evals(i) > last_core_ev) 1847 valence_indices.insert(i); 1848 // { 1849 // int i=0; 1850 // std::cout << "Valence eigenvalues:" << std::endl; 1851 // for (std::set<int>::const_iterator iter = valence_indices.begin(); 1852 // iter != valence_indices.end(); ++iter) 1853 // std::cout << i++ << "th eigenvalue is " << (*iter) << std::endl; 1854 // } 1855 } else { 1856 // just insert all indices 1857 for(int i=0;i<wfn->oso_dimension(); ++i) 1858 valence_indices.insert(i); 1859 } 1860 1861 // testing alternative routine from SCF::so_density() 1862 RefSCMatrix oso_vector = scf->oso_eigenvectors(); 1863 RefSCMatrix vector = scf->so_to_orthog_so().t() * oso_vector; 1864 oso_vector = 0; 1865 RefSymmSCMatrix occ(scf->oso_dimension(), scf->basis_matrixkit()); 1866 occ.assign(0.0); 1867 for (std::set<int>::const_iterator iter = valence_indices.begin(); 1868 iter != valence_indices.end(); ++iter) { 1869 const int i = *iter; 1870 occ(i,i) = scf->occupation(i); 1871 ExEnv::out0() << "# " << i << " has ev of " << evals(i) << ", occupied by " << scf->occupation(i) << std::endl; 1872 } 1873 RefSymmSCMatrix d2(scf->so_dimension(), scf->basis_matrixkit()); 1874 d2.assign(0.0); 1875 d2.accumulate_transform(vector, occ); 1876 1877 // taken from scf::density() 1878 RefSCMatrix nos 1879 = scf->integral()->petite_list()->evecs_to_AO_basis(scf->natural_orbitals()); 1880 RefDiagSCMatrix nd = scf->natural_density(); 1881 GaussianBasisSet::ValueData *valdat 1882 = new GaussianBasisSet::ValueData(scf->basis(), scf->integral()); 1883 std::vector<double>::iterator griditer = data.sampled_grid.sampled_grid.begin(); 1884 const int nbasis = scf->basis()->nbasis(); 1885 double *bs_values = new double[nbasis]; 1886 1887 // TODO: need to take care when we have periodic boundary conditions. 1888 for (size_t x = 0; x < samplepoints[0]; ++x, r.x() += delta(0)) { 1889 std::cout << "Sampling now for x=" << r.x() << std::endl; 1890 for (size_t y = 0; y < samplepoints[1]; ++y, r.y() += delta(1)) { 1891 for (size_t z = 0; z < samplepoints[2]; ++z, r.z() += delta(2)) { 1892 scf->basis()->values(r,valdat,bs_values); 1893 1894 // loop over natural orbitals adding contributions to elec_density 1895 double elec_density=0.0; 1896 for (int i=0; i<nbasis; ++i) { 1897 double tmp = 0.0; 1898 for (int j=0; j<nbasis; ++j) { 1899 tmp += d2(j,i)*bs_values[j]*bs_values[i]; 1900 } 1901 elec_density += tmp; 1902 } 1903 const double dens_at_r = elec_density * element_volume_conversion; 1904 // const double dens_at_r = scf->density(r) * element_volume_conversion; 1905 1906 // if (fabs(dens_at_r) > 1e-4) 1907 // std::cout << "Electron density at " << r << " is " << dens_at_r << std::endl; 1908 if (griditer != data.sampled_grid.sampled_grid.end()) 1909 *griditer++ = dens_at_r; 1910 else 1911 std::cerr << "PAST RANGE!" << std::endl; 1912 } 1913 r.z() = min.z(); 1914 } 1915 r.y() = min.y(); 1916 } 1917 delete[] bs_values; 1918 delete valdat; 1919 assert( griditer == data.sampled_grid.sampled_grid.end()); 1920 // normalization of electron charge to equal electron number 1921 { 1922 double integral_value = 0.; 1923 const double volume_element = pow(AtomicLengthToAngstroem,3)*delta(0)*delta(1)*delta(2); 1924 for (std::vector<double>::const_iterator diter = data.sampled_grid.sampled_grid.begin(); 1925 diter != data.sampled_grid.sampled_grid.end(); ++diter) 1926 integral_value += *diter; 1927 integral_value *= volume_element; 1928 int n_electrons = scf->nelectron(); 1929 if (data.DoValenceOnly == MPQCData::DoSampleValenceOnly) 1930 n_electrons -= wfn->molecule()->n_core_electrons(); 1931 const double normalization = 1932 ((integral_value == 0) || (n_electrons == 0)) ? 1933 1. : n_electrons/integral_value; 1934 std::cout << "Created " << data.sampled_grid.sampled_grid.size() << " grid points" 1935 << " with integral value of " << integral_value 1936 << " against " << ((data.DoValenceOnly == MPQCData::DoSampleValenceOnly) ? "n_valence_electrons" : "n_electrons") 1937 << " of " << n_electrons << "." << std::endl; 1938 // with normalization we also get the charge right : -1. 1939 for (std::vector<double>::iterator diter = data.sampled_grid.sampled_grid.begin(); 1940 diter != data.sampled_grid.sampled_grid.end(); ++diter) 1941 *diter *= -1.*normalization; 1942 } 1943 } 1944 } 1945 scf = 0; 1946 } 1947 if (tim.nonnull()) tim->exit("gather"); 1431 if (tim.nonnull()) tim->enter("extract"); 1432 extractResults(mole, data); 1433 if (tim.nonnull()) tim->exit("extract"); 1948 1434 1949 1435 if (print_timings) 1950 1436 if (tim.nonnull()) tim->print(ExEnv::out0()); 1951 1437 1952 1953 { 1954 // times obtain from key "mpqc" which should be the first 1955 const int nregion = tim->nregion(); 1956 //std::cout << "There are " << nregion << " timed regions." << std::endl; 1957 const char **region_names = new const char*[nregion]; 1958 tim->get_region_names(region_names); 1959 // find "gather" 1960 size_t gather_region = findTimerRegion(nregion, region_names, "gather"); 1961 size_t mpqc_region = findTimerRegion(nregion, region_names, "mpqc"); 1962 delete[] region_names; 1963 1964 // get timings 1965 double *cpu_time = new double[nregion]; 1966 double *wall_time = new double[nregion]; 1967 double *flops = new double[nregion]; 1968 tim->get_cpu_times(cpu_time); 1969 tim->get_wall_times(wall_time); 1970 tim->get_flops(flops); 1971 if (cpu_time != NULL) { 1972 data.times.total_cputime = cpu_time[mpqc_region]; 1973 data.times.gather_cputime = cpu_time[gather_region]; 1974 } 1975 if (wall_time != NULL) { 1976 data.times.total_walltime = wall_time[mpqc_region]; 1977 data.times.gather_walltime = wall_time[gather_region]; 1978 } 1979 if (flops != NULL) { 1980 data.times.total_flops = flops[mpqc_region]; 1981 data.times.gather_flops = flops[gather_region]; 1982 } 1983 delete[] cpu_time; 1984 delete[] wall_time; 1985 delete[] flops; 1986 } 1438 extractTimings(tim, data); 1987 1439 1988 1440 delete[] molname; … … 2001 1453 parsedkv = 0; 2002 1454 memory = 0; 2003 clean_up();1455 detail::clean_up(); 2004 1456 2005 1457 #if defined(HAVE_TIME) && defined(HAVE_CTIME) … … 2016 1468 2017 1469 // static values object 2018 OptionValues values; 2019 2020 #ifdef HAVE_JOBMARKET 2021 FragmentResult::ptr MPQCJob::Work() 2022 { 2023 char mpqc[] = "mpqc" ; 2024 char **argv = new char*[1]; 2025 argv[0] = &mpqc[0]; 2026 int argc = 1; 2027 // init(); 2028 // 2029 // ExEnv::init(argc, argv); 2030 // 2031 // // parse commandline options 2032 // GetLongOpt options; 2033 // int optind = ParseOptions(options, argc, argv); 2034 // const char *output = 0; 2035 // ostream *outstream = 0; 2036 // ComputeOptions(options, output, outstream); 2037 // OptionValues values; 2038 // parseRemainderOptions(options, values, argc, argv); 2039 // 2040 // // get the basename for output files 2041 // char filename_template[] = "mpqc_temp_XXXXXX"; 2042 // output = mktemp(filename_template); 2043 // setOutputBaseName(NULL, output); 2044 2045 // now comes the actual work 2046 int nfilebase = (int) inputfile.length(); 2047 char *in_char_array = new char[nfilebase + 1]; 2048 strncpy(in_char_array, inputfile.c_str(), nfilebase); 2049 in_char_array[nfilebase] = '\0'; 2050 const char *input = 0; 2051 const char *generic_input = 0; 2052 Ref<MessageGrp> grp = MessageGrp::get_default_messagegrp(); 2053 // create unique, temporary name and check whether it exists 2054 const char *output = NULL; 2055 char *tempfilename = NULL; 1470 detail::OptionValues values; 1471 1472 1473 namespace mpqc { 1474 1475 InitValues::InitValues() : 1476 input(NULL), 1477 object_input(NULL), 1478 generic_input(NULL), 1479 output(NULL), 1480 outstream(NULL), 1481 in_char_array(NULL), 1482 values(::values) 1483 {}; 1484 1485 void init(InitValues &_initvalues, int argc, char *argv[]) { 1486 1487 #if !defined(DEFAULT_MPI) && !defined(ALWAYS_USE_MPI) && defined(HAVE_MPI) 1488 MPI_Init(&argc, &argv); 1489 #endif 1490 1491 ::init(); 1492 1493 ExEnv::init(argc, argv); 1494 1495 } 1496 1497 void parseOptions(InitValues &_initvalues, int argc, char *argv[]) 2056 1498 { 2057 std::ifstream test; 2058 do { 2059 if (output != NULL) // free buffer from last round 2060 delete output; 2061 char filename_template[] = "mpqc_temp_XXXXXX\0"; 2062 char filename_suffix[] = ".in\0"; 2063 tempfilename = (char *) malloc ( (strlen(filename_template)+strlen(filename_suffix)+2)*(sizeof(char))); 2064 strncpy(tempfilename, mktemp(filename_template), strlen(filename_template)); 2065 tempfilename[strlen(filename_template)] = '\0'; 2066 strncat(tempfilename, filename_suffix, strlen(filename_suffix)); 2067 output = tempfilename; 2068 //free(tempfilename); // don't free! output takes over pointer! 2069 test.open(output); 2070 } while (test.good()); // test whether file does not(!) exist 2071 test.close(); 2072 } 2073 // put info how to sample the density into MPQCData 2074 MPQCData data(grid); 2075 data.DoLongrange = DoLongrange; // set whether we sample the density 2076 data.DoValenceOnly = DoValenceOnly; // set whether we sample just valence electron and nuclei densities 2077 // now call work horse 2078 try { 2079 mainFunction(grp, values, output, input, generic_input, in_char_array, argc, argv, data); 2080 } 2081 catch (SCException &e) { 2082 cout << argv[0] << ": ERROR: SC EXCEPTION RAISED:" << endl 2083 << e.what() 2084 << endl; 2085 clean_up(); 2086 } 2087 2088 //delete[] in_char_array; // is deleted in mainFunction() 2089 if (output != 0) { 2090 free(tempfilename); 2091 } 2092 delete[] argv; 2093 grp = NULL; 2094 2095 // place into returnstream 2096 std::stringstream returnstream; 2097 boost::archive::text_oarchive oa(returnstream); 2098 oa << data; 2099 2100 FragmentResult::ptr s( new FragmentResult(getId(), returnstream.str()) ); 2101 if (s->exitflag != 0) 2102 cerr << "Job #" << s->getId() << " failed to reach desired accuracy." << endl; 2103 2104 return s; 2105 } 2106 #endif 2107 2108 // we need to explicitly instantiate the serialization functions as 2109 // its is only serialized through its base class FragmentJob 2110 BOOST_CLASS_EXPORT_IMPLEMENT(MPQCJob) 1499 // parse commandline options 1500 int optind = ParseOptions(_initvalues.options, argc, argv); 1501 ComputeOptions(_initvalues.options, _initvalues.output, _initvalues.outstream); 1502 parseRemainderOptions(_initvalues.options, _initvalues.values, argc, argv); 1503 1504 // get input file names, either object-oriented or generic 1505 getInputFileNames(_initvalues.object_input, _initvalues.generic_input, _initvalues.options, optind, argc, argv); 1506 if (_initvalues.object_input) 1507 _initvalues.input = _initvalues.object_input; 1508 if (_initvalues.generic_input) 1509 _initvalues.input = _initvalues.generic_input; 1510 1511 // get the message group. first try the commandline and environment 1512 getMessageGroup(_initvalues.grp, argc, argv); 1513 } 1514 1515 void cleanup(InitValues &_initvalues) { 1516 if (_initvalues.output != 0) { 1517 ExEnv::set_out(&cout); 1518 delete _initvalues.outstream; 1519 } 1520 1521 _initvalues.grp = 0; 1522 final_clean_up(); 1523 1524 #if !defined(DEFAULT_MPI) && !defined(ALWAYS_USE_MPI) && defined(HAVE_MPI) 1525 // there is an MPI_Finalize() hidden somewhere else 1526 // MPI_Finalize(); 1527 #endif 1528 } 1529 1530 } /* namespace mpqc */ 1531 1532 namespace detail { 2111 1533 2112 1534 int 2113 1535 try_main(int argc, char *argv[]) 2114 1536 { 2115 init(); 2116 2117 ExEnv::init(argc, argv); 2118 2119 // parse commandline options 2120 GetLongOpt options; 2121 int optind = ParseOptions(options, argc, argv); 2122 const char *output = 0; 2123 ostream *outstream = 0; 2124 ComputeOptions(options, output, outstream); 2125 parseRemainderOptions(options, values, argc, argv); 2126 2127 // get input file names, either object-oriented or generic 2128 const char *object_input = 0; 2129 const char *generic_input = 0; 2130 getInputFileNames(object_input, generic_input, options, optind, argc, argv); 2131 const char *input = 0; 2132 if (object_input) input = object_input; 2133 if (generic_input) input = generic_input; 2134 2135 // get the message group. first try the commandline and environment 2136 Ref<MessageGrp> grp; 2137 getMessageGroup(grp, argc, argv); 1537 mpqc::InitValues initvalues; 1538 1539 mpqc::init(initvalues, argc, argv); 1540 1541 mpqc::parseOptions(initvalues, argc, argv); 2138 1542 2139 1543 // check if we got option "-n" 2140 1544 int exitflag = 0; 2141 #ifdef HAVE_JOBMARKET 2142 if (options.retrieve("n")) { 2143 /// create new argc, argv and call by splitting with tokenizer 2144 std::string networkstring(options.retrieve("n")); 2145 typedef boost::tokenizer<boost::char_separator<char> > tokenizer; 2146 boost::char_separator<char> sep(" "); 2147 tokenizer tok(networkstring, sep); 2148 // simple count because tokenizer has now size() 2149 int argc_network = 0; 2150 for(tokenizer::iterator beg=tok.begin(); beg!=tok.end();++beg) 2151 ++argc_network; 2152 // argv[0] is program name 2153 char **argv_network = new char*[argc_network+1]; 2154 argv_network[0] = new char[5]; 2155 strcpy(argv_network[0], "mpqc"); 2156 // then we place each token as a new argument 2157 argc_network = 1; 2158 for(tokenizer::iterator beg=tok.begin(); beg!=tok.end();++beg){ 2159 const size_t strlength = (*beg).length(); 2160 const char *strarray = beg->c_str(); 2161 //std::cout << "Token " << argc_network << " is " << strarray << ", length " << strlength << endl; 2162 argv_network[argc_network] = new char[strlength+1]; 2163 strcpy(argv_network[argc_network], strarray); 2164 argv_network[argc_network][strlength] = '\0'; 2165 for (size_t index = 0; index < strlength; ++index) 2166 if (argv_network[argc_network][index] == '+') 2167 argv_network[argc_network][index] = '-'; 2168 ++argc_network; 2169 } 2170 /// and start listening for MPQCJobs 2171 exitflag = poolworker_main(argc_network, argv_network); 2172 /// remove the artifical [argv,argv] again 2173 for (int i=0;i<argc_network;++i) 2174 delete[] argv_network[i]; 2175 delete[] argv_network; 2176 } else 2177 #endif 2178 { 2179 // if not, work on the command line input 2180 char *in_char_array = 0; 2181 #ifdef HAVE_MPQCDATA 2182 MPQCData data; 2183 mainFunction(grp, values, output, input, generic_input, in_char_array, argc, argv, data); 2184 #else 2185 mainFunction(grp, values, output, input, generic_input, in_char_array, argc, argv); 2186 #endif 2187 } 2188 2189 if (output != 0) { 2190 ExEnv::set_out(&cout); 2191 delete outstream; 2192 } 2193 2194 grp = 0; 2195 final_clean_up(); 1545 void *data = NULL; 1546 mpqc::mainFunction( 1547 initvalues, 1548 argc, argv, 1549 data); 1550 1551 mpqc::cleanup(initvalues); 2196 1552 2197 1553 return exitflag; 2198 1554 } 2199 1555 1556 } /* namespace detail */ 2200 1557 2201 1558 double EvaluateDensity(SCVector3 &r, Ref<Integral> &intgrl, GaussianBasisSet::ValueData &vdat, Ref<Wavefunction> &wfn) … … 2212 1569 } 2213 1570 2214 int2215 main(int argc, char *argv[])2216 {2217 #if !defined(DEFAULT_MPI) && !defined(ALWAYS_USE_MPI) && defined(HAVE_MPI)2218 MPI_Init(&argc, &argv);2219 #endif2220 size_t exitflag = 0;2221 try {2222 exitflag = try_main(argc, argv);2223 }2224 catch (SCException &e) {2225 cout << argv[0] << ": ERROR: SC EXCEPTION RAISED:" << endl2226 << e.what()2227 << endl;2228 clean_up();2229 throw;2230 }2231 catch (bad_alloc &e) {2232 cout << argv[0] << ": ERROR: MEMORY ALLOCATION FAILED:" << endl2233 << e.what()2234 << endl;2235 clean_up();2236 throw;2237 }2238 catch (exception &e) {2239 cout << argv[0] << ": ERROR: EXCEPTION RAISED:" << endl2240 << e.what()2241 << endl;2242 clean_up();2243 throw;2244 }2245 catch (...) {2246 cout << argv[0] << ": ERROR: UNKNOWN EXCEPTION RAISED" << endl;2247 clean_up();2248 throw;2249 }2250 #if !defined(DEFAULT_MPI) && !defined(ALWAYS_USE_MPI) && defined(HAVE_MPI)2251 // there is an MPI_Finalize() hidden somewhere else2252 // MPI_Finalize();2253 #endif2254 return exitflag;2255 }2256 2257 1571 ///////////////////////////////////////////////////////////////////////////// 2258 1572
Note:
See TracChangeset
for help on using the changeset viewer.