/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2012 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * Filler.cpp * * Created on: Jan 16, 2012 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include #include #include #include #include #include "Filler.hpp" #include "CodePatterns/Assert.hpp" #include "CodePatterns/Log.hpp" #include "Atom/atom.hpp" #include "ClusterInterface.hpp" #include "Descriptors/AtomIdDescriptor.hpp" #include "LinearAlgebra/Vector.hpp" #include "NodeTypes.hpp" #include "Predicates/FillPredicate.hpp" #include "Predicates/Ops_FillPredicate.hpp" #include "World.hpp" /** Constructor for class Filler. * * \note We store inverted \a _predicate because we need it only for * remove_copy_if which works in this inverted way as desired. * * @param mesh Mesh with a NodeSet that fills its Shape * @param predicate predicate construct to check at each Node */ Filler::Filler(const Mesh &_mesh, const FillPredicate &_predicate) : mesh(_mesh), predicate(!_predicate) {} /** Destructor for class Filler. * */ Filler::~Filler() {} /** Fill in the desired Cluster at each remaining node. * * \note The cluster is non-const because it is moved to the first vacant node. * * @param copyMethod functor that knows how to copy atoms. * @param cluster set of atomic ids contained in a specific Shape to fill each Node with */ void Filler::operator()( CopyAtomsInterface ©Method, ClusterInterface::Cluster_impl cluster) const { const NodeSet &nodes = mesh.getNodes(); std::stringstream output; std::for_each( nodes.begin(), nodes.end(), output << boost::lambda::_1 << " "); LOG(3, "DEBUG: Listing nodes to check: " << output.str()); if (nodes.size() == 0) { ASSERT(false, "Filler::operator() - Mesh contains no nodes."); return; } NodeSet FillNodes(nodes.size(), zeroVec); // evaluate predicate and gather into new set NodeSet::iterator transform_end = std::remove_copy_if(nodes.begin(), nodes.end(), FillNodes.begin(), predicate ); FillNodes.erase(transform_end, FillNodes.end()); if (FillNodes.size() == 0) { ELOG(2, "For none of the nodes did the predicate return true."); return; } else { LOG(1, "INFO: " << FillNodes.size() << " out of " << nodes.size() << " returned true from predicate."); } // skip first node (as we must keep the original atoms) NodeSet::iterator iter = ++FillNodes.begin(); // fill all other true nodes std::for_each(iter , FillNodes.end(), boost::bind(&ClusterInterface::clone, boost::cref(cluster), boost::ref(copyMethod), _1) ); // move cluster to first node cluster->translate(*FillNodes.begin()); }