/*
* Project: MoleCuilder
* Description: creates and alters molecular systems
* Copyright (C) 2010-2012 University of Bonn. All rights reserved.
* Copyright (C) 2013 Frederik Heber. All rights reserved.
*
*
* This file is part of MoleCuilder.
*
* MoleCuilder is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* MoleCuilder is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MoleCuilder. If not, see .
*/
/*
* ParserPsi3UnitTest.cpp
*
* Created on: Mar 3, 2010
* Author: metzler
*/
// include config.h
#ifdef HAVE_CONFIG_H
#include
#endif
#include "ParserPsi3UnitTest.hpp"
#include
#include
#include
#include
#include "CodePatterns/Log.hpp"
#include "Atom/atom.hpp"
#include "Atom/AtomObserver.hpp"
#include "Element/element.hpp"
#include "Element/periodentafel.hpp"
#include "CodePatterns/Assert.hpp"
#include "Descriptors/AtomTypeDescriptor.hpp"
#include "Parser/ChangeTracker.hpp"
#include "Parser/Psi3Parser.hpp"
#include "World.hpp"
#ifdef HAVE_TESTRUNNER
#include "UnitTestMain.hpp"
#endif /*HAVE_TESTRUNNER*/
using namespace std;
// Registers the fixture into the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION( ParserPsi3UnitTest );
static string hydrogenPsi3_RHF ="% Created by MoleCuilder\n\
psi: (\n\
\tlabel = \"cc-pVTZ SCF H2\"\n\
\tjobtype = sp\n\
\twfn = scf\n\
\tmaxiter = 80\n\
\treference = rhf\n\
\tbasis = \"cc-pVTZ\"\n\
\tfreeze_core = no\n\
\tunits = angstrom\n\
\tgeometry = (\n\
\t( H\t0\t0\t-0.37 )\n\
\t( H\t0\t0\t0.37 )\n\
\t)\n\
\torigin = (0.0\t0.0\t0.0)\n\
)\n"; // tested with ???
static string hydrogenPsi3_ROHF ="% Created by MoleCuilder\n\
psi: (\n\
\tlabel = \"cc-pVTZ SCF H2\"\n\
\tjobtype = sp\n\
\twfn = scf\n\
\tmaxiter = 80\n\
\treference = rohf\n\
\tbasis = \"cc-pVTZ\"\n\
\tfreeze_core = no\n\
\tunits = angstrom\n\
\tgeometry = (\n\
\t( H\t0\t0\t-0.37 )\n\
\t( H\t0\t0\t0.37 )\n\
\t)\n\
\torigin = (0.0\t0.0\t0.0)\n\
)\n"; // tested with ???
static string hydrogenPsi3_UHF ="% Created by MoleCuilder\n\
psi: (\n\
\tlabel = \"cc-pVTZ SCF H2\"\n\
\tjobtype = sp\n\
\twfn = scf\n\
\tmaxiter = 80\n\
\treference = uhf\n\
\tbasis = \"cc-pVTZ\"\n\
\tmultp = 3\n\
\tcharge = 2\n\
\tfreeze_core = no\n\
\tunits = angstrom\n\
\tgeometry = (\n\
\t( H\t0\t0\t-0.37 )\n\
\t( H\t0\t0\t0.37 )\n\
\t)\n\
\torigin = (0.0\t0.0\t0.0)\n\
)\n"; // tested with ???
static string hydrogenPsi3_TWOCON ="% Created by MoleCuilder\n\
psi: (\n\
\tlabel = \"cc-pVTZ SCF H2\"\n\
\tjobtype = sp\n\
\twfn = scf\n\
\tmaxiter = 80\n\
\treference = twocon\n\
\tbasis = \"cc-pVTZ\"\n\
\tmultp = 3\n\
\tcharge = 2\n\
\tsocc = ( 1 1 0 0 0 0 0 0 )\n\
\tdocc = ( 0 0 0 0 0 0 0 0 )\n\
\tsubgroup = c2v\n\
\tunique_axis = x\n\
\tfreeze_core = no\n\
\tunits = angstrom\n\
\tgeometry = (\n\
\t( H\t0\t0\t-0.37 )\n\
\t( H\t0\t0\t0.37 )\n\
\t)\n\
\torigin = (0.0\t0.0\t0.0)\n\
)\n"; // tested with ???
void ParserPsi3UnitTest::setUp()
{
// failing asserts should be thrown
ASSERT_DO(Assert::Throw);
parser = new FormatParser();
params = &parser->getParams();
World::getInstance();
setVerbosity(2);
// we need hydrogens and oxygens in the following tests
CPPUNIT_ASSERT(World::getInstance().getPeriode()->FindElement(1) != NULL);
}
void ParserPsi3UnitTest::tearDown()
{
params = NULL;
delete parser;
ChangeTracker::purgeInstance();
World::purgeInstance();
AtomObserver::purgeInstance();
}
/************************************ tests ***********************************/
void ParserPsi3UnitTest::ParameterDefaultTest() {
// check default values
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::labelParam) == std::string("unknown job"));
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::jobtypeParam) == params->ValidJobtypes[Psi3Parser_Parameters::SP]);
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::wavefunctionParam) == params->ValidWavefunction[Psi3Parser_Parameters::SCF]);
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::maxiterParam) == std::string("80"));
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::referenceParam) == params->ValidReference[Psi3Parser_Parameters::RHF]);
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::basisParam) == std::string("cc-pVTZ"));
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::freeze_coreParam) == params->ValidFreezeCore[Psi3Parser_Parameters::YES]);
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::unitsParam) == params->ValidUnits[Psi3Parser_Parameters::angstrom]);
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::dertypeParam) == params->ValidDerivativeType[Psi3Parser_Parameters::NONE]);
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::originParam) == std::string("(0.0\t0.0\t0.0)"));
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::multiplicityParam) == std::string("1"));
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::chargeParam) == std::string("0"));
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::soccParam) == std::string("()"));
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::doccParam) == std::string("()"));
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::subgroupParam) == std::string(""));
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::unique_axisParam) == params->ValidUniqueAxis[Psi3Parser_Parameters::X]);
}
void ParserPsi3UnitTest::ParameterCloneTest() {
FormatParser_Parameters *clone = params->clone();
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::jobtypeParam) == params->ValidJobtypes[Psi3Parser_Parameters::SP]);
std::stringstream setvalue(params->ParamNames[Psi3Parser_Parameters::jobtypeParam]+"="+params->ValidJobtypes[Psi3Parser_Parameters::OPT]);
setvalue >> *params;
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::jobtypeParam) == params->ValidJobtypes[Psi3Parser_Parameters::OPT]);
params->makeClone(*clone);
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::jobtypeParam) == params->ValidJobtypes[Psi3Parser_Parameters::SP]);
}
void ParserPsi3UnitTest::ParameterSetterTest() {
// test a jobtype
{
std::stringstream setvalue(
params->ParamNames[Psi3Parser_Parameters::jobtypeParam]
+" = "+params->ValidJobtypes[Psi3Parser_Parameters::OPT]
);
setvalue >> *params;
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::jobtypeParam) == params->ValidJobtypes[Psi3Parser_Parameters::OPT]);
}
// test a wavefunction
{
std::stringstream setvalue(
params->ParamNames[Psi3Parser_Parameters::wavefunctionParam]
+" = "+params->ValidWavefunction[Psi3Parser_Parameters::MP2]
);
setvalue >> *params;
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::wavefunctionParam) == params->ValidWavefunction[Psi3Parser_Parameters::MP2]);
}
// test a reference
{
std::stringstream setvalue(
params->ParamNames[Psi3Parser_Parameters::referenceParam]
+" = "+params->ValidReference[Psi3Parser_Parameters::ROHF]
);
setvalue >> *params;
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::referenceParam) == params->ValidReference[Psi3Parser_Parameters::ROHF]);
}
// test a unique_axis
{
std::stringstream setvalue(
params->ParamNames[Psi3Parser_Parameters::unique_axisParam]
+" = "+params->ValidUniqueAxis[Psi3Parser_Parameters::Y]
);
setvalue >> *params;
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::unique_axisParam) == params->ValidUniqueAxis[Psi3Parser_Parameters::Y]);
}
// test a units
{
std::stringstream setvalue(
params->ParamNames[Psi3Parser_Parameters::unitsParam]
+" = "+params->ValidUnits[Psi3Parser_Parameters::bohr]
);
setvalue >> *params;
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::unitsParam) == params->ValidUnits[Psi3Parser_Parameters::bohr]);
}
// test a dertype
{
std::stringstream setvalue(
params->ParamNames[Psi3Parser_Parameters::dertypeParam]
+" = "+params->ValidDerivativeType[Psi3Parser_Parameters::NONE]
);
setvalue >> *params;
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::dertypeParam) == params->ValidDerivativeType[Psi3Parser_Parameters::NONE]);
}
// test a freeze_core
{
std::stringstream setvalue(
params->ParamNames[Psi3Parser_Parameters::freeze_coreParam]
+" = "+params->ValidFreezeCore[Psi3Parser_Parameters::LARGE]
);
setvalue >> *params;
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::freeze_coreParam) == params->ValidFreezeCore[Psi3Parser_Parameters::LARGE]);
}
// test int
{
std::stringstream setvalue(
params->ParamNames[Psi3Parser_Parameters::maxiterParam]
+" = 500"
);
setvalue >> *params;
// std::cout << "maxiter is "
// << params->getString(Psi3Parser_Parameters::maxiterParam) << std::endl;
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::maxiterParam) == std::string("500"));
}
// test whether unknown key fails
std::cout << "The following Assertion warning is desired and does not indicate a failure of the test." << std::endl;
{
std::stringstream setvalue("sd = no");
#ifndef NDEBUG
ASSERT_DO(Assert::Throw);
CPPUNIT_ASSERT_THROW(setvalue >> *params, Assert::AssertionFailure);
#else
setvalue >> *params;
#endif
// std::cout << "Hessian is still "
// << params->getString(Psi3Parser_Parameters::hessianParam) << std::endl;
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::jobtypeParam) == params->ValidJobtypes[Psi3Parser_Parameters::OPT]);
}
}
void ParserPsi3UnitTest::readPsi3Test() {
stringstream input(hydrogenPsi3_RHF);
// set some other parameter for jobtype
params->setParameter(
Psi3Parser_Parameters::jobtypeParam,
params->ValidJobtypes[Psi3Parser_Parameters::OPT]
);
parser->load(&input);
// check for jobtype from file
CPPUNIT_ASSERT(params->getParameter(Psi3Parser_Parameters::jobtypeParam) == params->ValidJobtypes[Psi3Parser_Parameters::SP]);
// check for 2 hydrogens
CPPUNIT_ASSERT_EQUAL(2, World::getInstance().numAtoms());
// check that positions are right
Vector PositionSum;
std::vector atoms = World::getInstance().getAllAtoms();
for (std::vector::const_iterator iter = atoms.begin();
iter != atoms.end();
++iter)
PositionSum += (*iter)->getPosition();
CPPUNIT_ASSERT_EQUAL( PositionSum, Vector(0.,0.,0.) );
}
void ParserPsi3UnitTest::writePsi3Test() {
// build up hydrogen molecule
string first;
string second;
atom *Walker = NULL;
Walker = World::getInstance().createAtom();
Walker->setType(1);
Walker->setPosition(Vector(0.,0.,0.));
Walker = World::getInstance().createAtom();
Walker->setType(1);
Walker->setPosition(Vector(0.,0,0.74));
CPPUNIT_ASSERT_EQUAL(2, World::getInstance().numAtoms());
// set general parameters: label and freeze_core
params->setParameter(
Psi3Parser_Parameters::labelParam,
"cc-pVTZ SCF H2"
);
params->setParameter(
Psi3Parser_Parameters::freeze_coreParam,
params->ValidFreezeCore[Psi3Parser_Parameters::NO]
);
params->setParameter(
Psi3Parser_Parameters::unitsParam,
params->ValidUnits[Psi3Parser_Parameters::angstrom]
);
// create two stringstreams, one stored, one created
std::vector atoms = World::getInstance().getAllAtoms();
{
// compare both configs for RHF
stringstream output;
params->setParameter(
Psi3Parser_Parameters::referenceParam,
params->ValidReference[Psi3Parser_Parameters::RHF]
);
parser->save(&output, atoms);
stringstream input(hydrogenPsi3_RHF);
// check for non-empty streams
input.peek();
output.peek();
CPPUNIT_ASSERT(input.good() && output.good());
// check equality of streams per line (for debugging)
for (; std::getline(input, first) && std::getline(output, second); ) {
//std::cout << "Comparing '" << first << "' to '" << second << "'" << std::endl;
CPPUNIT_ASSERT(first == second);
}
}
{
// compare both configs for ROHF
stringstream output;
params->setParameter(
Psi3Parser_Parameters::referenceParam,
params->ValidReference[Psi3Parser_Parameters::ROHF]
);
parser->save(&output, atoms);
stringstream input(hydrogenPsi3_ROHF);
// check for non-empty streams
input.peek();
output.peek();
CPPUNIT_ASSERT(input.good() && output.good());
// check equality of streams per line (for debugging)
for (; std::getline(input, first) && std::getline(output, second); ) {
//std::cout << "Comparing '" << first << "' to '" << second << "'" << std::endl;
CPPUNIT_ASSERT(first == second);
}
}
{
params->setParameter(Psi3Parser_Parameters::multiplicityParam, "2");
params->setParameter(Psi3Parser_Parameters::chargeParam, "2");
// compare both configs for UHF
stringstream output;
params->setParameter(
Psi3Parser_Parameters::referenceParam,
params->ValidReference[Psi3Parser_Parameters::UHF]
);
parser->save(&output, atoms);
params->setParameter(Psi3Parser_Parameters::chargeParam, "0");
params->setParameter(Psi3Parser_Parameters::multiplicityParam, "1");
stringstream input(hydrogenPsi3_UHF);
// check for non-empty streams
input.peek();
output.peek();
CPPUNIT_ASSERT(input.good() && output.good());
// check equality of streams per line (for debugging)
for (; std::getline(input, first) && std::getline(output, second); ) {
//std::cout << "Comparing '" << first << "' to '" << second << "'" << std::endl;
CPPUNIT_ASSERT(first == second);
}
}
{
params->setParameter(Psi3Parser_Parameters::multiplicityParam, "1");
params->setParameter(Psi3Parser_Parameters::chargeParam, "2");
params->setParameter(Psi3Parser_Parameters::soccParam, "( 1 1 0 0 0 0 0 0 )");
params->setParameter(Psi3Parser_Parameters::doccParam, "( 0 0 0 0 0 0 0 0 )");
params->setParameter(Psi3Parser_Parameters::subgroupParam, "c2v");
params->setParameter(Psi3Parser_Parameters::unique_axisParam, "x");
// compare both configs for TWOCON
stringstream output;
params->setParameter(
Psi3Parser_Parameters::referenceParam,
params->ValidReference[Psi3Parser_Parameters::TWOCON]
);
parser->save(&output, atoms);
params->setParameter(Psi3Parser_Parameters::multiplicityParam, "1");
params->setParameter(Psi3Parser_Parameters::chargeParam, "0");
stringstream input(hydrogenPsi3_TWOCON);
// check for non-empty streams
input.peek();
output.peek();
CPPUNIT_ASSERT(input.good() && output.good());
// check equality of streams per line (for debugging)
for (; std::getline(input, first) && std::getline(output, second); ) {
//std::cout << "Comparing '" << first << "' to '" << second << "'" << std::endl;
CPPUNIT_ASSERT(first == second);
}
}
}