/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 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 . */ /* * ApproximateShapeVolume.cpp * * Created on: Jan 30, 2012 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include "ApproximateShapeVolume.hpp" #include #include #include "Box.hpp" #include "Filling/Mesh/CubeMesh.hpp" #include "Filling/NodeTypes.hpp" #include "LinearAlgebra/RealSpaceMatrix.hpp" #include "LinearAlgebra/Vector.hpp" #include "World.hpp" /** Constructor of class ApproximateShapeVolume. * * @param _shape shape to calculate the volume approximately */ ApproximateShapeVolume::ApproximateShapeVolume(const Shape &_shape) : shape(_shape) {} /** Destructor of class ApproximateShapeVolume. * */ ApproximateShapeVolume::~ApproximateShapeVolume() {} /** Calculate the approximate volume of the given \a shape. * * @return surface volume approximated */ double ApproximateShapeVolume::operator()() const { // TODO // generate mesh of points to "integrate" const double min_distance = 10.; Vector distance(min_distance,min_distance,min_distance); const RealSpaceMatrix &M = World::getInstance().getDomain().getM(); Mesh *mesh = new CubeMesh(distance, Vector(0.5,0.5,0.5), M ); NodeSet nodes = mesh->getNodes(); // fill with grid points and count whether isInside const size_t total = nodes.size(); size_t inside = 0; for (NodeSet::const_iterator iter = nodes.begin(); iter != nodes.end(); ++iter) { if (shape.isInside(*iter)) ++inside; } // calculate volume of box const double volume = M.determinant(); // return fraction that is inside return volume*((double)inside/(double)total); }