/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010-2012 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * bondgraph.cpp * * Created on: Oct 29, 2009 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include #include "Atom/atom.hpp" #include "Bond/bond.hpp" #include "Graph/BondGraph.hpp" #include "Box.hpp" #include "Element/element.hpp" #include "CodePatterns/Info.hpp" #include "CodePatterns/Log.hpp" #include "CodePatterns/Range.hpp" #include "CodePatterns/Verbose.hpp" #include "molecule.hpp" #include "Element/periodentafel.hpp" #include "Fragmentation/MatrixContainer.hpp" #include "LinearAlgebra/Vector.hpp" #include "World.hpp" #include "WorldTime.hpp" const double BondGraph::BondThreshold = 0.4; //!< CSD threshold in bond check which is the width of the interval whose center is the sum of the covalent radii BondGraph::BondGraph() : BondLengthMatrix(NULL), IsAngstroem(true) {} BondGraph::BondGraph(bool IsA) : BondLengthMatrix(NULL), IsAngstroem(IsA) {} BondGraph::~BondGraph() { CleanupBondLengthTable(); } void BondGraph::CleanupBondLengthTable() { if (BondLengthMatrix != NULL) { delete(BondLengthMatrix); } } bool BondGraph::LoadBondLengthTable( std::istream &input) { Info FunctionInfo(__func__); bool status = true; MatrixContainer *TempContainer = NULL; // allocate MatrixContainer if (BondLengthMatrix != NULL) { LOG(1, "MatrixContainer for Bond length already present, removing."); delete(BondLengthMatrix); BondLengthMatrix = NULL; } TempContainer = new MatrixContainer; // parse in matrix if ((input.good()) && (status = TempContainer->ParseMatrix(input, 0, 1, 0))) { LOG(1, "Parsing bond length matrix successful."); } else { ELOG(1, "Parsing bond length matrix failed."); status = false; } if (status) // set to not NULL only if matrix was parsed BondLengthMatrix = TempContainer; else { BondLengthMatrix = NULL; delete(TempContainer); } return status; } double BondGraph::GetBondLength( int firstZ, int secondZ) const { double return_length; if ((firstZ < 0) || (firstZ >= (int)BondLengthMatrix->Matrix[0].size())) return -1.; if ((secondZ < 0) || (secondZ >= (int)BondLengthMatrix->Matrix[0][firstZ].size())) return -1.; if (BondLengthMatrix == NULL) { return_length = -1.; } else { return_length = BondLengthMatrix->Matrix[0][firstZ][secondZ]; } LOG(4, "INFO: Request for length between " << firstZ << " and " << secondZ << ": " << return_length << "."); return return_length; } range BondGraph::CovalentMinMaxDistance( const element * const Walker, const element * const OtherWalker) const { range MinMaxDistance(0.,0.); MinMaxDistance.first = OtherWalker->getCovalentRadius() + Walker->getCovalentRadius(); MinMaxDistance.first *= (IsAngstroem) ? 1. : 1. / AtomicLengthToAngstroem; MinMaxDistance.last = MinMaxDistance.first + BondThreshold; MinMaxDistance.first -= BondThreshold; return MinMaxDistance; } range BondGraph::BondLengthMatrixMinMaxDistance( const element * const Walker, const element * const OtherWalker) const { ASSERT(BondLengthMatrix, "BondGraph::BondLengthMatrixMinMaxDistance() called without NULL BondLengthMatrix."); ASSERT(Walker, "BondGraph::BondLengthMatrixMinMaxDistance() - illegal element given."); ASSERT(OtherWalker, "BondGraph::BondLengthMatrixMinMaxDistance() - illegal other element given."); range MinMaxDistance(0.,0.); MinMaxDistance.first = GetBondLength(Walker->getAtomicNumber()-1, OtherWalker->getAtomicNumber()-1); MinMaxDistance.first *= (IsAngstroem) ? 1. : 1. / AtomicLengthToAngstroem; MinMaxDistance.last = MinMaxDistance.first + BondThreshold; MinMaxDistance.first -= BondThreshold; return MinMaxDistance; } range BondGraph::getMinMaxDistance( const element * const Walker, const element * const OtherWalker) const { range MinMaxDistance(0.,0.); if (BondLengthMatrix == NULL) {// safety measure if no matrix has been parsed yet LOG(2, "INFO: Using Covalent radii criterion for [min,max) distances."); MinMaxDistance = CovalentMinMaxDistance(Walker, OtherWalker); } else { LOG(2, "INFO: Using Covalent radii criterion for [min,max) distances."); MinMaxDistance = BondLengthMatrixMinMaxDistance(Walker, OtherWalker); } return MinMaxDistance; } range BondGraph::getMinMaxDistance( const BondedParticle * const Walker, const BondedParticle * const OtherWalker) const { return getMinMaxDistance(Walker->getType(), OtherWalker->getType()); } range BondGraph::getMinMaxDistanceSquared( const BondedParticle * const Walker, const BondedParticle * const OtherWalker) const { // use non-squared version range MinMaxDistance(getMinMaxDistance(Walker, OtherWalker)); // and square MinMaxDistance.first *= MinMaxDistance.first; MinMaxDistance.last *= MinMaxDistance.last; return MinMaxDistance; } LinkedCell::LinkedCell_View BondGraph::getLinkedCell(const double max_distance) const { return World::getInstance().getLinkedCell(max_distance); } std::set< const element *> BondGraph::getElementSetFromNumbers(const std::set &Set) const { std::set< const element *> PresentElements; for(std::set::const_iterator iter = Set.begin(); iter != Set.end(); ++iter) PresentElements.insert( World::getInstance().getPeriode()->FindElement(*iter) ); return PresentElements; } Box &BondGraph::getDomain() const { return World::getInstance().getDomain(); } unsigned int BondGraph::getTime() const { return WorldTime::getTime(); } bool BondGraph::operator==(const BondGraph &other) const { if (IsAngstroem != other.IsAngstroem) return false; if (((BondLengthMatrix != NULL) && (other.BondLengthMatrix == NULL)) || ((BondLengthMatrix == NULL) && (other.BondLengthMatrix != NULL))) return false; if ((BondLengthMatrix != NULL) && (other.BondLengthMatrix != NULL)) if (*BondLengthMatrix != *other.BondLengthMatrix) return false; return true; }