/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * MpqcParser_Parameters.cpp * * Created on: Feb 3, 2011 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "CodePatterns/MemDebug.hpp" #include "CodePatterns/Log.hpp" #include "CodePatterns/Verbose.hpp" #include "MpqcParser.hpp" #include "MpqcParser_Parameters.hpp" using boost::any_cast; MpqcParser_Parameters::MpqcParser_Parameters() { Init(); } void MpqcParser_Parameters::Init() { // add all known basis initBasis(); // add all theory names TheoryNames[CLHF]="CLHF"; TheoryNames[CLKS]="CLKS"; TheoryNames[MBPT2]="MBPT2"; TheoryNames[MBPT2_R12]="MBPT2_R12"; { // TODO: throw exception instead of eLog() std::pair inserter; for (TheoryNamesType::iterator iter = TheoryNames.begin(); iter != TheoryNames.end(); ++iter) { inserter = TheoryLookup.insert( make_pair(iter->second, iter->first) ); if (!inserter.second) DoeLog(0) && (eLog() << Verbose(0) << "MpqcParser_Parameters::MpqcParser_Parameters() - Theory name already present: " << (inserter.first)->second << " and " << iter->first << "!" << std::endl); } } // add all integration names IntegrationNames[IntegralCints] = "IntegralCints"; { // TODO: throw exception instead of eLog() std::pair inserter; for (IntegrationNamesType::iterator iter = IntegrationNames.begin(); iter != IntegrationNames.end(); ++iter) { inserter = IntegrationLookup.insert( make_pair(iter->second, iter->first) ); if (!inserter.second) DoeLog(0) && (eLog() << Verbose(0) << "MpqcParser_Parameters::MpqcParser_Parameters() - Integration name already present: " << (inserter.first)->second << " and " << iter->first << "!" << std::endl); } } // have names for all parmaters ParamNames[hessianParam] = "Hessian"; ParamNames[savestateParam] = "savestate"; ParamNames[do_gradientParam] = "do_gradient"; ParamNames[maxiterParam] = "maxiter"; ParamNames[memoryParam] = "memory"; ParamNames[stdapproxParam] = "stdapprox"; ParamNames[nfzcParam] = "nfzc"; ParamNames[basisParam] = "basis"; ParamNames[aux_basisParam] = "aux_basis"; ParamNames[integrationParam] = "integration"; ParamNames[theoryParam] = "theory"; { // TODO: throw exception instead of eLog() std::pair inserter; for (ParamNamesType::iterator iter = ParamNames.begin(); iter != ParamNames.end(); ++iter) { inserter = ParamLookup.insert( make_pair(iter->second, iter->first) ); if (!inserter.second) DoeLog(0) && (eLog() << Verbose(0) << "MpqcParser_Parameters::MpqcParser_Parameters() - parameter name already present: " << (inserter.first)->second << " and " << iter->first << "!" << std::endl); } } initParameters(); } MpqcParser_Parameters::MpqcParser_Parameters(const MpqcParser_Parameters & state) { // init Init(); // copy values copyParameters(state); } void MpqcParser_Parameters::copyParameters(const MpqcParser_Parameters & state) { appendParameter(hessianParam, state.getBool(hessianParam)); appendParameter(savestateParam, state.getBool(savestateParam)); appendParameter(do_gradientParam, state.getBool(do_gradientParam)); appendParameter(maxiterParam, state.getInt(maxiterParam)); appendParameter(memoryParam, state.getInt(memoryParam)); appendParameter(stdapproxParam, state.getString(stdapproxParam)); appendParameter(nfzcParam, state.getInt(nfzcParam)); appendParameter(basisParam, state.getString(basisParam)); appendParameter(aux_basisParam, state.getString(aux_basisParam)); appendParameter(integrationParam, state.getIntegration()); appendParameter(theoryParam, state.getTheory()); } FormatParser_Parameters* MpqcParser_Parameters::clone() const { //LOG(3, "Cloning parameters."); MpqcParser_Parameters *instance = new MpqcParser_Parameters(*this); return instance; } void MpqcParser_Parameters::makeClone(const FormatParser_Parameters & _state) { //LOG(3, "Cloning parameters from other instance."); copyParameters(static_cast(_state)); } void MpqcParser_Parameters::initParameters() { appendParameter(hessianParam, bool(false)); appendParameter(savestateParam, bool(false)); appendParameter(do_gradientParam, bool(true)); appendParameter(maxiterParam, int(1000)); appendParameter(memoryParam, int(16000000)); appendParameter(stdapproxParam, std::string("A'")); appendParameter(nfzcParam, int(1)); appendParameter(basisParam, std::string("3-21G")); appendParameter(aux_basisParam, std::string("aug-cc-pVDZ")); appendParameter(integrationParam, IntegralCints); appendParameter(theoryParam, MBPT2); } MpqcParser_Parameters::~MpqcParser_Parameters() {} std::ostream & operator << (std::ostream& ost, MpqcParser_Parameters const &_mpqc_params) { // this is ugly, but with boost::any to safeguard const-ness is plain impossible MpqcParser_Parameters &mpqc_params = const_cast(_mpqc_params); std::ostringstream output; output << "Hessian=" << mpqc_params.getBool(MpqcParser_Parameters::hessianParam) << ";"; output << "savestate=" << mpqc_params.getBool(MpqcParser_Parameters::savestateParam) << ";"; output << "do_gradient=" << mpqc_params.getBool(MpqcParser_Parameters::do_gradientParam) << ";"; output << "maxiter=" << mpqc_params.getInt(MpqcParser_Parameters::maxiterParam) << ";"; output << "memory=" << mpqc_params.getInt(MpqcParser_Parameters::memoryParam) << ";"; output << "stdapprox=" << mpqc_params.getString(MpqcParser_Parameters::stdapproxParam) << ";"; output << "nfzc=" << mpqc_params.getInt(MpqcParser_Parameters::nfzcParam) << ";"; output << "basis=" << mpqc_params.getString(MpqcParser_Parameters::basisParam) << ";"; output << "aux_basis=" << mpqc_params.getString(MpqcParser_Parameters::aux_basisParam) << ";"; output << "integration=" << mpqc_params.getString(MpqcParser_Parameters::integrationParam) << ";"; output << "theory=" << mpqc_params.getString(MpqcParser_Parameters::theoryParam) << ";"; ost << output.str(); return ost; } std::istream & operator >> (std::istream& ist, MpqcParser_Parameters ¶ms) { typedef boost::tokenizer > tokenizer; boost::char_separator semicolonsep(";"); boost::char_separator equalitysep(" ="); boost::char_separator ticksep("\""); std::string line; std::getline( ist, line ); //DoLog(0) && (Log() << Verbose(0) << "INFO: full line of parameters is '" << line << "'" << std::endl); tokenizer tokens(line, semicolonsep); ASSERT(tokens.begin() != tokens.end(), "operator<< on MpqcParser_Parameters - empty string, need at least ';' in line "+line+"!"); for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) { tokenizer paramtokens(*tok_iter, equalitysep); if (paramtokens.begin() != paramtokens.end()) { tokenizer::iterator tok_paramiter = paramtokens.begin(); tokenizer::iterator tok_valueiter = tok_paramiter; tokenizer::iterator tok_checkiter = ++tok_valueiter; ++tok_checkiter; // TODO: throw exception instead of ASSERT ASSERT(tok_paramiter != paramtokens.end(), "operator<< on MpqcParser_Parameters - missing value before ' =' in token "+*tok_iter+"!"); ASSERT(tok_valueiter != paramtokens.end(), "operator<< on MpqcParser_Parameters - missing value after ' =' in token "+*tok_iter+"!"); ASSERT(tok_checkiter == paramtokens.end(), "operator<< on MpqcParser_Parameters - still more tokens after ' =' in token "+*tok_iter+":" +*tok_checkiter+"!"); std::stringstream keystream(*tok_paramiter); std::string key; keystream >> ws >> key; tokenizer ticklesstokens(*tok_valueiter, ticksep); ASSERT(ticklesstokens.begin() != ticklesstokens.end(), "operator<< on MpqcParser_Parameters - no tokens present after removing ticks in token "+*tok_valueiter+"!"); std::stringstream valuestream(*(ticklesstokens.begin())); DoLog(2) && (Log() << Verbose(2) << "INFO: Token pair is " << key << "," << valuestream.str() << std::endl); // TODO: throw exception instead of DoeLog() ASSERT(params.haveParam(key), "operator >> on MpqcParser_Parameters - unknown parameter name '" +key+"' with value "+valuestream.str()+"!"); if (params.haveParam(key)) params.setter(params.getParam(key), valuestream); } else { ist.setstate(std::ios::eofbit); } } return ist; } /** Sets a desired value in the params from a string. * * This is due to strict typing of C++ very ugly and boost::any does not make * it any better because it offers to functions to use values directly from * stringstream. Probably, because value is unknown to is as well and hence * the author could not implement it beautifully, so he dropped it altogether. * Grrr .... * * @param _param param to set * @param _desired stringstream containing value as next argument * @return true - type ok, false - unknown type in params. */ bool MpqcParser_Parameters::setter(enum Parameters _param, std::stringstream& _desired) { if (_param == integrationParam) { std::string tmp; _desired >> tmp; params[_param] = IntegrationLookup[tmp]; } else if(_param == theoryParam) { std::string tmp; _desired >> tmp; params[_param] = TheoryLookup[tmp]; } else if (params[_param].type() == typeid(std::string)) { std::string tmp; _desired >> tmp; params[_param] = tmp; } else if (params[_param].type() == typeid(int)) { int tmp; _desired >> tmp; params[_param] = tmp; } else if (params[_param].type() == typeid(double)) { double tmp; _desired >> tmp; params[_param] = tmp; } else if (params[_param].type() == typeid(bool)) { std::string tmp; _desired >> tmp; if ((tmp == "yes") || (tmp == "1")) { params[_param] = bool(true); } else if ((tmp == "no") || (tmp == "0")) { params[_param] = bool(false); } else { DoeLog(0) && (eLog() << Verbose(0) << "MpqcParser_Parameters::setter() - unknown boolean key " << tmp << "!" << std::endl); } } else { DoeLog(0) && (eLog() << Verbose(0) << "MpqcParser_Parameters::setter() - unknown type!" << std::endl); return false; } return true; } void MpqcParser_Parameters::setTheory(enum Theory _theory) { // TODO: throw exception instead of eLog() // try { params[theoryParam] = _theory; // } catch(const boost::bad_any_cast &) { // DoeLog(0) && (eLog() << Verbose(0) // << "MpqcParser_Parameters::setTheory() - could not set boolean!" << std::endl); // } } void MpqcParser_Parameters::setIntegration(enum MpqcParser_Parameters::IntegrationMethod _integration){ // TODO: throw exception instead of eLog() // try { params[integrationParam] = _integration; // } catch(const boost::bad_any_cast &) { // DoeLog(0) && (eLog() << Verbose(0) // << "MpqcParser_Parameters::setIntegration() - could not set boolean!" << std::endl); // } } bool MpqcParser_Parameters::haveParam(std::string _name) const { return ParamLookup.count(_name) != 0; } enum MpqcParser_Parameters::Parameters MpqcParser_Parameters::getParam(std::string _name) const { ParamLookupType::const_iterator iter = ParamLookup.find(_name); return iter->second; } enum MpqcParser_Parameters::IntegrationMethod MpqcParser_Parameters::getIntegration() const { parameterlist::const_iterator iter = params.find(integrationParam); enum IntegrationMethod value; // TODO: throw exception instead of eLog() // try { value = boost::any_cast(iter->second); // } catch(const boost::bad_any_cast &) { // DoeLog(0) && (eLog() << Verbose(0) // << "MpqcParser_Parameters::getIntegration() - could not convert " // +ParamNames[integrationParam]+" to enum IntegrationMethod!" << std::endl); // } return value; } enum MpqcParser_Parameters::Theory MpqcParser_Parameters::getTheory() const { parameterlist::const_iterator iter = params.find(theoryParam); enum Theory value; // TODO: throw exception instead of eLog() // try { value = boost::any_cast(iter->second); // } catch(const boost::bad_any_cast &) { // DoeLog(0) && (eLog() << Verbose(0) // << "MpqcParser_Parameters::getTheory() - could not convert " // +ParamNames[theoryParam]+" to enum Theory!" << std::endl); // } return value; } std::string MpqcParser_Parameters::getString(enum Parameters _param) const { std::string value; enum IntegrationMethod Iindex; enum Theory Tindex; bool test; parameterlist::const_iterator iter = params.find(_param); switch (_param) { case hessianParam: case savestateParam: case do_gradientParam: test = boost::any_cast(iter->second); if (test) value = "yes"; else value = "no"; break; case integrationParam: // TODO: throw exception instead of eLog() // try { Iindex = boost::any_cast(iter->second); // } catch(const boost::bad_any_cast &) { // DoeLog(0) && (eLog() << Verbose(0) // << "MpqcParser_Parameters::getString() - could not convert " // +ParamNames[_param]+" to string!" << std::endl); // } { IntegrationNamesType::const_iterator Iiter = IntegrationNames.find(Iindex); value = Iiter->second; } break; case theoryParam: // TODO: throw exception instead of eLog() // try { Tindex = boost::any_cast(iter->second); // } catch(const boost::bad_any_cast &) { // DoeLog(0) && (eLog() << Verbose(0) // << "MpqcParser_Parameters::getString() - could not convert " // +ParamNames[_param]+" to string!" << std::endl); // } { TheoryNamesType::const_iterator Titer = TheoryNames.find(Tindex); value = Titer->second; } break; default: // TODO: throw exception instead of eLog() // try { value = boost::any_cast(iter->second); // } catch(const boost::bad_any_cast &) { // DoeLog(0) && (eLog() << Verbose(0) // << "MpqcParser_Parameters::getString() - could not convert " // +ParamNames[_param]+" to string!" << std::endl); // } break; } return value; } int MpqcParser_Parameters::getInt(enum Parameters _param) const { int value; parameterlist::const_iterator iter = params.find(_param); switch (_param) { default: // TODO: throw exception instead of eLog() // try { value = boost::any_cast(iter->second); // } catch(const boost::bad_any_cast &) { // DoeLog(0) && (eLog() << Verbose(0) // << "MpqcParser_Parameters::getInt() - could not convert " // +ParamNames[_param]+" to int!" << std::endl); // } break; } return value; } double MpqcParser_Parameters::getDouble(enum Parameters _param) const { double value; parameterlist::const_iterator iter = params.find(_param); // TODO: throw exception instead of eLog() // try { value = boost::any_cast(iter->second); // } catch(const boost::bad_any_cast &) { // DoeLog(0) && (eLog() << Verbose(0) // << "MpqcParser_Parameters::getDouble() - could not convert " // +ParamNames[_param]+" to double!" << std::endl); // } return value; } bool MpqcParser_Parameters::getBool(enum Parameters _param) const { bool value; parameterlist::const_iterator iter = params.find(_param); // TODO: throw exception instead of eLog() // try { value = boost::any_cast(iter->second); // } catch(const boost::bad_any_cast &) { // DoeLog(0) && (eLog() << Verbose(0) // << "MpqcParser_Parameters::getBool() - could not convert " // +ParamNames[_param]+" to bool!" << std::endl); // } return value; } /** Checks whether all elements in the world also have parameters in the basis. * * @return true - all elements parametrized, false - at least one element is missing. */ bool MpqcParser_Parameters::checkWorldElementsAgainstCurrentBasis() const { DoeLog(0) && (eLog() << Verbose(0) << "MpqcParser_Parameters::checkWorldElementsAgainstCurrentBasis() - not implemented yet." << std::endl); return false; }