/* * 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. */ /** \file builder.cpp * * date: Jan 1, 2007 * author: heber * */ /*! \page Copyright notice * * MoleCuilder - to create and alter molecular systems * Copyright (C) 2010 University Bonn. All rights reserved. * */ /*! \mainpage MoleCuilder - a molecular set builder * * This introductory shall briefly make acquainted with the program, helping in installing and a first run. * * \section about About the Program * * MoleCuilder is a program, written entirely in C++, that enables the construction of a coordinate set for the * atoms making up an molecule. It allows for both building of simple molecules by adding atom-wise giving bond * angles and distances or absolute coordinates, but also using them as templates. Regions can be specified and * ordered to be filled with a molecule in a certain manner. Greater conglomerations of molecules can be tesselated * and recognized as a region themselves to be subsequently surrounded by other (surface solvated) molecules. * In the end, MoleCuilder allows the construction of arbitrary nano structures, whether they be crystalline or * amorphic in nature. * * * \section install Installation * * Installation should without problems succeed as follows: * -# ./configure (or: mkdir build;mkdir run;cd build; ../configure --bindir=../run) * -# make * -# make install * * Further useful commands are * -# make clean uninstall: deletes .o-files and removes executable from the given binary directory\n * -# make doxygen-doc: Creates these html pages out of the documented source * -# make check: Runs an extensive set of unit tests and a testsuite which also gives a good overview on the set of * functions. * * \section run Running * * The program can be executed by running: ./molecuilder * * MoleCuilder has three interfaces at your disposal: * -# Textmenu: A simple interactive console-based menu, where awaits your choices and inputs in order to set atoms * as you like * -# CommandLineUI: Every command can also be chained up as a sequence of actions on the command line to be executed * with any user interaction. * -# GraphicalUI: A graphical user interface that also display the molecular structure being built and lots of other * informations to ease the construction of bigger geometries. * * The supported output formats right now are: * -# mpqc: Configuration files of the Massively Parallel Quantum Chemistry package (Sandia labs) * -# pcp: Configuration files of the Parallel Car-Parrinello program (Institute for Numerical Simulation) * -# tremolo: Configuration files of TREMOLO (Institute for Numerical Simulation) * -# xyz: the most basic format for the 3d arrangement of atoms consisting of a list of element and 3 coordinates. * */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "Helpers/MemDebug.hpp" #include "bondgraph.hpp" #include "config.hpp" #include "Helpers/Log.hpp" #include "molecule.hpp" #include "periodentafel.hpp" #include "tesselationhelpers.hpp" #include "UIElements/UIFactory.hpp" #include "UIElements/Menu/MenuDescription.hpp" #include "UIElements/TextUI/TextUIFactory.hpp" #include "UIElements/CommandLineUI/CommandLineUIFactory.hpp" #include "UIElements/CommandLineUI/CommandLineParser.hpp" #ifdef USE_GUI_QT #include "UIElements/Qt4/QtUIFactory.hpp" #endif #include "UIElements/MainWindow.hpp" #include "UIElements/Dialog.hpp" //#include "Menu/ActionMenuItem.hpp" #include "Helpers/Verbose.hpp" #include "World.hpp" #include "Actions/ActionRegistry.hpp" #include "Actions/ActionHistory.hpp" #include "Parser/ChangeTracker.hpp" #include "Parser/FormatParserStorage.hpp" #include "UIElements/UIFactory.hpp" #include "UIElements/TextUI/TextUIFactory.hpp" #include "UIElements/CommandLineUI/CommandLineUIFactory.hpp" #include "UIElements/MainWindow.hpp" #include "UIElements/Dialog.hpp" #include "version.h" /********************************************** Main routine **************************************/ /** In this function all dynamicly allocated member variables to static/global * variables are added to the ignore list of Memory/MemDebug. * * Use this to prevent their listing in the Memory::getState() at the end of the * program. Check with valgrind that truely no memory leak occurs! */ void AddStaticEntitiestoIgnoreList() { // zeroVec and unitVec are global variables (on the stack) but vectorContent // within is situated on the heap and has to be ignored Memory::ignore(zeroVec.get()); Memory::ignore(unitVec[0].get()); Memory::ignore(unitVec[1].get()); Memory::ignore(unitVec[2].get()); } /** Cleans all singleton instances in an orderly fashion. * C++ does not guarantee any specific sequence of removal of single instances * which have static/global variables. Some singletons depend on others hence we * acertain a specific ordering here, which is is used via the atexit() hook. */ void cleanUp(){ FormatParserStorage::purgeInstance(); ChangeTracker::purgeInstance(); World::purgeInstance(); MenuDescription::purgeInstance(); UIFactory::purgeInstance(); ValueStorage::purgeInstance(); CommandLineParser::purgeInstance(); ActionRegistry::purgeInstance(); OptionRegistry::purgeInstance(); ActionHistory::purgeInstance(); // we have to remove these two static as otherwise their boost::shared_ptrs are still present Action::removeStaticStateEntities(); // put some static variables' dynamic contents on the Memory::ignore map to avoid their // admonishing lateron AddStaticEntitiestoIgnoreList(); logger::purgeInstance(); errorLogger::purgeInstance(); #ifdef LOG_OBSERVER cout << observerLog().getLog(); #endif Memory::getState(); } void dumpMemory(){ ofstream ost("molecuilder.memdump"); Memory::dumpMemory(ost); } int main(int argc, char **argv) { // while we are non interactive, we want to abort from asserts ASSERT_DO(Assert::Abort); ASSERT_HOOK(dumpMemory); string line; char **Arguments = NULL; int ArgcSize = 0; int ExitFlag = 0; bool ArgumentsCopied = false; std::string BondGraphFileName("\n"); // print version check and copyright notice cout << MOLECUILDERVERSION << endl; cout << "MoleCuilder comes with ABSOLUTELY NO WARRANTY; for details type" << endl; cout << "`molecuilder --warranty'." << endl; cout << "`MoleCuilder - to create and alter molecular systems." << endl; cout << "Copyright (C) 2010 University Bonn. All rights reserved." << endl; setVerbosity(0); // need to init the history before any action is created ActionHistory::init(); // from this moment on, we need to be sure to deeinitialize in the correct order // this is handled by the cleanup function atexit(cleanUp); // Parse command line options and if present create respective UI { // construct bond graph if (World::getInstance().getConfig()->BG == NULL) { World::getInstance().getConfig()->BG = new BondGraph(World::getInstance().getConfig()->GetIsAngstroem()); if (World::getInstance().getConfig()->BG->LoadBondLengthTable(BondGraphFileName)) { DoLog(0) && (Log() << Verbose(0) << "Bond length table loaded successfully." << endl); } else { DoeLog(1) && (eLog()<< Verbose(1) << "Bond length table loading failed." << endl); } } // handle remaining arguments by CommandLineParser if (argc>1) { CommandLineParser::getInstance().InitializeCommandArguments(); CommandLineParser::getInstance().Run(argc,argv); DoLog(0) && (Log() << Verbose(0) << "Setting UI to CommandLine." << endl); UIFactory::registerFactory(new CommandLineUIFactory::description()); UIFactory::makeUserInterface("CommandLine"); } else { // In the interactive mode, we can leave the user the choice in case of error ASSERT_DO(Assert::Ask); #ifdef USE_GUI_QT DoLog(0) && (Log() << Verbose(0) << "Setting UI to Qt4." << endl); UIFactory::registerFactory(new QtUIFactory::description()); UIFactory::makeUserInterface("Qt4"); #else DoLog(0) && (Log() << Verbose(0) << "Setting UI to Text." << endl); cout << MOLECUILDERVERSION << endl; UIFactory::registerFactory(new TextUIFactory::description()); UIFactory::makeUserInterface("Text"); #endif } } { MainWindow *mainWindow = UIFactory::getInstance().makeMainWindow(); mainWindow->display(); delete mainWindow; } FormatParserStorage::getInstance().SaveAll(); ChangeTracker::getInstance().saveStatus(); // free the new argv if (ArgumentsCopied) { for (int i=0; i