/*
* Project: MoleCuilder
* Description: creates and alters molecular systems
* Copyright (C) 2010-2012 University of Bonn. 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 .
*/
/** \file analyzer.cpp
*
* Takes evaluated fragments (energy and forces) and does evaluation of how sensible the BOSSANOVA
* approach was, e.g. in the decay of the many-body-contributions.
*
*/
//============================ INCLUDES ===========================
// include config.h
#ifdef HAVE_CONFIG_H
#include
#endif
#include "CodePatterns/MemDebug.hpp"
#include
#include
#include
#include
#include "datacreator.hpp"
#include "Element/periodentafel.hpp"
#include "Fragmentation/defs.hpp"
#include "Fragmentation/EnergyMatrix.hpp"
#include "Fragmentation/ForceMatrix.hpp"
#include "Fragmentation/helpers.hpp"
#include "Fragmentation/HessianMatrix.hpp"
#include "Fragmentation/KeySetsContainer.hpp"
#include "CodePatterns/Log.hpp"
#include "CodePatterns/Verbose.hpp"
//============================== MAIN =============================
int main(int argc, char **argv)
{
periodentafel *periode = NULL; // and a period table of all elements
EnergyMatrix Energy;
EnergyMatrix EnergyFragments;
ForceMatrix Force;
ForceMatrix ForceFragments;
HessianMatrix Hessian;
HessianMatrix HessianFragments;
EnergyMatrix Hcorrection;
EnergyMatrix HcorrectionFragments;
ForceMatrix Shielding;
ForceMatrix ShieldingPAS;
ForceMatrix Chi;
ForceMatrix ChiPAS;
EnergyMatrix Time;
ForceMatrix ShieldingFragments;
ForceMatrix ShieldingPASFragments;
ForceMatrix ChiFragments;
ForceMatrix ChiPASFragments;
KeySetsContainer KeySet;
std::ofstream output;
std::ofstream output2;
std::ofstream output3;
std::ofstream output4;
std::ifstream input;
std::stringstream filename;
time_t t = time(NULL);
struct tm *ts = localtime(&t);
char *datum = asctime(ts);
std::stringstream Orderxrange;
std::stringstream Fragmentxrange;
std::stringstream yrange;
char *dir = NULL;
bool NoHessian = false;
bool NoTime = false;
bool NoHCorrection = true;
int counter = 0;
LOG(0, "ANOVA Analyzer");
LOG(0, "==============");
// Get the command line options
if (argc < 4) {
LOG(0, "Usage: " << argv[0] << " [elementsdb]");
LOG(0, "\ttherein the output of a molecuilder fragmentation is expected, each fragment with a subdir containing an energy.all and a forces.all file.");
LOG(0, "\tprefix of energy and forces file.");
LOG(0, "\tcreated plotfiles and datafiles are placed into this directory ");
LOG(0, "[elementsdb]\tpath to elements database, needed for shieldings.");
return 1;
} else {
dir = new char[strlen(argv[2]) + 2];
strcpy(dir, "/");
strcat(dir, argv[2]);
}
if (argc > 4) {
LOG(0, "Loading periodentafel.");
periode = new periodentafel;
periode->LoadPeriodentafel(argv[4]);
}
// Test the given directory
if (!TestParams(argc, argv)) {
delete dir;
delete periode;
return 1;
}
// +++++++++++++++++ PARSING +++++++++++++++++++++++++++++++
// ------------- Parse through all Fragment subdirs --------
if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix,0,0)) return 1;
if (!Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX,0,0)) {
NoHCorrection = true;
ELOG(2, "No HCorrection file found, skipping these.");
}
if (!Force.ParseFragmentMatrix(argv[1], dir, ForcesSuffix,0,0)) return 1;
if (!Hessian.ParseFragmentMatrix(argv[1], dir, HessianSuffix,0,0)) {
NoHessian = true;
ELOG(2, "No Hessian file found, skipping these.");
}
if (!Time.ParseFragmentMatrix(argv[1], dir, TimeSuffix, 10,1)) {
NoTime = true;
ELOG(2, "No speed file found, skipping these.");
}
if (periode != NULL) { // also look for PAS values
if (!Shielding.ParseFragmentMatrix(argv[1], dir, ShieldingSuffix, 1, 0)) return 1;
if (!ShieldingPAS.ParseFragmentMatrix(argv[1], dir, ShieldingPASSuffix, 1, 0)) return 1;
if (!Chi.ParseFragmentMatrix(argv[1], dir, ChiSuffix, 1, 0)) return 1;
if (!ChiPAS.ParseFragmentMatrix(argv[1], dir, ChiPASSuffix, 1, 0)) return 1;
}
// ---------- Parse the TE Factors into an array -----------------
if (!Energy.ParseIndices()) return 1;
if (!NoHCorrection) Hcorrection.ParseIndices();
// ---------- Parse the Force indices into an array ---------------
if (!Force.ParseIndices(argv[1])) return 1;
if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return 1;
if (!ForceFragments.InitialiseIndices((class MatrixContainer *)&Force)) return 1;
// ---------- Parse hessian indices into an array -----------------
if (!NoHessian) {
if (!Hessian.InitialiseIndices((class MatrixContainer *)&Force)) return 1;
if (!HessianFragments.AllocateMatrix(Hessian.Header, Hessian.MatrixCounter, Hessian.RowCounter, Hessian.ColumnCounter)) return 1;
if (!HessianFragments.InitialiseIndices((class MatrixContainer *)&Force)) return 1;
}
// ---------- Parse the shielding indices into an array ---------------
if (periode != NULL) { // also look for PAS values
if(!Shielding.ParseIndices(argv[1])) return 1;
if(!ShieldingPAS.ParseIndices(argv[1])) return 1;
if (!ShieldingFragments.AllocateMatrix(Shielding.Header, Shielding.MatrixCounter, Shielding.RowCounter, Shielding.ColumnCounter)) return 1;
if (!ShieldingPASFragments.AllocateMatrix(ShieldingPAS.Header, ShieldingPAS.MatrixCounter, ShieldingPAS.RowCounter, ShieldingPAS.ColumnCounter)) return 1;
if(!ShieldingFragments.ParseIndices(argv[1])) return 1;
if(!ShieldingPASFragments.ParseIndices(argv[1])) return 1;
if(!Chi.ParseIndices(argv[1])) return 1;
if(!ChiPAS.ParseIndices(argv[1])) return 1;
if (!ChiFragments.AllocateMatrix(Chi.Header, Chi.MatrixCounter, Chi.RowCounter, Chi.ColumnCounter)) return 1;
if (!ChiPASFragments.AllocateMatrix(ChiPAS.Header, ChiPAS.MatrixCounter, ChiPAS.RowCounter, ChiPAS.ColumnCounter)) return 1;
if(!ChiFragments.ParseIndices(argv[1])) return 1;
if(!ChiPASFragments.ParseIndices(argv[1])) return 1;
}
// ---------- Parse the KeySets into an array ---------------
{
std::stringstream filename;
filename << FRAGMENTPREFIX << KEYSETFILE;
if (!KeySet.ParseKeySets(argv[1], filename.str(), Force.MatrixCounter)) return 1;
}
if (!KeySet.ParseManyBodyTerms()) return 1;
// ---------- Parse fragment files created by 'joiner' into an array -------------
if (!EnergyFragments.ParseFragmentMatrix(argv[1], dir, EnergyFragmentSuffix,0,0)) return 1;
if (!NoHCorrection)
HcorrectionFragments.ParseFragmentMatrix(argv[1], dir, HcorrectionFragmentSuffix,0,0);
if (!ForceFragments.ParseFragmentMatrix(argv[1], dir, ForceFragmentSuffix,0,0)) return 1;
if (!NoHessian)
if (!HessianFragments.ParseFragmentMatrix(argv[1], dir, HessianFragmentSuffix,0,0)) return 1;
if (periode != NULL) { // also look for PAS values
if (!ShieldingFragments.ParseFragmentMatrix(argv[1], dir, ShieldingFragmentSuffix, 1, 0)) return 1;
if (!ShieldingPASFragments.ParseFragmentMatrix(argv[1], dir, ShieldingPASFragmentSuffix, 1, 0)) return 1;
if (!ChiFragments.ParseFragmentMatrix(argv[1], dir, ChiFragmentSuffix, 1, 0)) return 1;
if (!ChiPASFragments.ParseFragmentMatrix(argv[1], dir, ChiPASFragmentSuffix, 1, 0)) return 1;
}
// +++++++++++++++ TESTING ++++++++++++++++++++++++++++++
// print energy and forces to file
filename.str("");
filename << argv[3] << "/" << "energy-forces.all";
output.open(filename.str().c_str(), ios::out);
output << endl << "Total Energy" << endl << "==============" << endl << Energy.Header[Energy.MatrixCounter] << endl;
for(int j=0;j MYEPSILON)
output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k] / Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k];
else
output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k];
}
output << endl;
output2 << endl;
}
output.close();
output2.close();
}
if (!NoHessian) {
// +++++++++++++++++++++++++++++++++++++++ Plotting deviation in hessian to full QM
if (!CreateDataDeltaHessianOrderPerAtom(Hessian, HessianFragments, KeySet, argv[3], "DeltaHessian_xx-Order", "Plot of error between approximated hessian and full hessian versus the Bond Order", datum)) return 1;
if (!CreateDataDeltaFrobeniusOrderPerAtom(Hessian, HessianFragments, KeySet, argv[3], "DeltaFrobeniusHessian_xx-Order", "Plot of error between approximated hessian and full hessian in the frobenius norm versus the Bond Order", datum)) return 1;
// ++++++++++++++++++++++++++++++++++++++Plotting Hessian vs. Order
if (!CreateDataHessianOrderPerAtom(HessianFragments, KeySet, argv[3], "Hessian_xx-Order", "Plot of approximated hessian versus the Bond Order", datum)) return 1;
if (!AppendOutputFile(output, argv[3], "Hessian_xx-Order.dat" )) return false;
output << endl << "# Full" << endl;
for(int j=0;j1) && (k<6))? 1.e6 : 1.) << "\t";
output << endl;
}
output.close();
if (!CreateDataDeltaForcesOrderPerAtom(ChiPAS, ChiPASFragments, KeySet, argv[3], "DeltaChisPAS-Order", "Plot of error between approximated Chis and full Chis versus the Bond Order", datum)) return 1;
if (!CreateDataForcesOrderPerAtom(ChiPASFragments, KeySet, argv[3], "ChisPAS-Order", "Plot of approximated Chis versus the Bond Order", datum)) return 1;
if (!AppendOutputFile(output, argv[3], "ChisPAS-Order.dat" )) return false;
output << endl << "# Full" << endl;
for(int j=0;j1) && (k<6))? 1.e6 : 1.) << "\t";
output << endl;
}
output.close();
}
// +++++++++++++++++++++++++++++++++++++++ Plotting deviation in energy to full QM
if (!CreateDataDeltaEnergyOrder(Energy, EnergyFragments, KeySet, argv[3], "DeltaEnergies-Order", "Plot of error between approximated and full energies energies versus the Bond Order", datum)) return 1;
// +++++++++++++++++++++++++++++++++++Plotting Energies vs. Order
if (!CreateDataEnergyOrder(EnergyFragments, KeySet, argv[3], "Energies-Order", "Plot of approximated energies versus the Bond Order", datum)) return 1;
// +++++++++++++++++++++++++++++++++++++++ Plotting deviation in forces to full QM
if (!CreateDataDeltaForcesOrderPerAtom(Force, ForceFragments, KeySet, argv[3], "DeltaForces-Order", "Plot of error between approximated forces and full forces versus the Bond Order", datum)) return 1;
// min force
if (!CreateDataDeltaForcesOrder(Force, ForceFragments, KeySet, argv[3], "DeltaMinForces-Order", "Plot of min error between approximated forces and full forces versus the Bond Order", datum, CreateMinimumForce)) return 1;
// mean force
if (!CreateDataDeltaForcesOrder(Force, ForceFragments, KeySet, argv[3], "DeltaMeanForces-Order", "Plot of mean error between approximated forces and full forces versus the Bond Order", datum, CreateMeanForce)) return 1;
// max force
if (!CreateDataDeltaForcesOrder(Force, ForceFragments, KeySet, argv[3], "DeltaMaxForces-Order", "Plot of max error between approximated forces and full forces versus the Bond Order", datum, CreateMaximumForce)) return 1;
// ++++++++++++++++++++++++++++++++++++++Plotting Forces vs. Order
if (!CreateDataForcesOrderPerAtom(ForceFragments, KeySet, argv[3], "Forces-Order", "Plot of approximated forces versus the Bond Order", datum)) return 1;
if (!AppendOutputFile(output, argv[3], "Forces-Order.dat" )) return false;
output << endl << "# Full" << endl;
for(int j=0;j