/* * PCMSolver, an API for the Polarizable Continuum Model * Copyright (C) 2020 Roberto Di Remigio, Luca Frediani and contributors. * * This file is part of PCMSolver. * * PCMSolver is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * PCMSolver 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with PCMSolver. If not, see . * * For information on the complete list of contributors to the * PCMSolver API, see: */ #pragma once #include #include #include "Config.hpp" #include #include "Element.hpp" #include "utils/Molecule.hpp" #include "utils/Sphere.hpp" #include "utils/Symmetry.hpp" /*! \file ICavity.hpp */ namespace pcm { using cavity::Element; using utils::Sphere; /*! \class ICavity * \brief Abstract Base Class for cavities. * \author Krzysztof Mozgawa * \date 2011 * * This class represents a cavity made of spheres, its surface being discretized in * terms of finite elements. */ class ICavity { protected: /// List of spheres std::vector spheres_; /// The molecule to be wrapped by the cavity Molecule molecule_; /// Number of finite elements generated PCMSolverIndex nElements_; /// Number of irreducible finite elements PCMSolverIndex nIrrElements_; /// Whether the cavity has been built bool built; /// Coordinates of elements centers Eigen::Matrix3Xd elementCenter_; /// Outward-pointing normal vectors to the elements centers Eigen::Matrix3Xd elementNormal_; /// Elements areas Eigen::VectorXd elementArea_; /// Number of spheres int nSpheres_; /// Centers of the sphere the elements belong to Eigen::Matrix3Xd elementSphereCenter_; /// Radii of the sphere the elements belong to Eigen::VectorXd elementRadius_; /// Spheres centers Eigen::Matrix3Xd sphereCenter_; /// Spheres radii Eigen::VectorXd sphereRadius_; /// List of finite elements std::vector elements_; /// Molecular point group Symmetry pointGroup_; private: /*! \brief Creates the cavity and discretizes its surface. * * Has to be implemented by classes lower down in the inheritance hierarchy */ virtual void makeCavity() = 0; virtual std::ostream & printCavity(std::ostream & os) = 0; public: //! Default constructor ICavity(); /*! \brief Constructor from a single sphere * \param[in] sph the sphere * * Only used when we have to deal with a single sphere, i.e. in the unit tests */ ICavity(const Sphere & sph); /*! \brief Constructor from list of spheres * \param[in] sph the list of spheres * * Only used when we have to deal with a single sphere, i.e. in the unit tests */ ICavity(const std::vector & sph); /*! \brief Constructor from Molecule * \param[in] molec the molecular aggregate */ ICavity(const Molecule & molec); virtual ~ICavity() {} Eigen::Matrix3Xd & elementCenter() { return elementCenter_; } const Eigen::Matrix3Xd & elementCenter() const { return elementCenter_; } Eigen::Vector3d elementCenter(int i) { return elementCenter_.col(i); } Eigen::Vector3d elementCenter(int i) const { return elementCenter_.col(i); } Eigen::Matrix3Xd & elementNormal() { return elementNormal_; } const Eigen::Matrix3Xd & elementNormal() const { return elementNormal_; } Eigen::Vector3d elementNormal(int i) { return elementNormal_.col(i); } Eigen::Vector3d elementNormal(int i) const { return elementNormal_.col(i); } Eigen::VectorXd & elementArea() { return elementArea_; } const Eigen::VectorXd & elementArea() const { return elementArea_; } double elementArea(int i) { return elementArea_(i); } double elementArea(int i) const { return elementArea_(i); } PCMSolverIndex size() { return nElements_; } PCMSolverIndex size() const { return nElements_; } PCMSolverIndex irreducible_size() { return nIrrElements_; } PCMSolverIndex irreducible_size() const { return nIrrElements_; } Symmetry pointGroup() const { return molecule_.pointGroup(); } std::vector & spheres() { return spheres_; } const std::vector & spheres() const { return spheres_; } int nSpheres() { return nSpheres_; } int nSpheres() const { return nSpheres_; } Eigen::VectorXd & sphereRadius() { return sphereRadius_; } const Eigen::VectorXd & sphereRadius() const { return sphereRadius_; } Eigen::Matrix3Xd & sphereCenter() { return sphereCenter_; } const Eigen::Matrix3Xd & sphereCenter() const { return sphereCenter_; } Eigen::VectorXd & elementRadius() { return elementRadius_; } const Eigen::VectorXd & elementRadius() const { return elementRadius_; } double elementRadius(int i) { return elementRadius_(i); } double elementRadius(int i) const { return elementRadius_(i); } Eigen::Matrix3Xd & elementSphereCenter() { return elementSphereCenter_; } const Eigen::Matrix3Xd & elementSphereCenter() const { return elementSphereCenter_; } bool isBuilt() { return built; } const std::vector & elements() const { return elements_; } const Element & elements(int i) const { return elements_[i]; } /*! \brief Save cavity specification to file. * * The cavity specification contains: * 0. the number of finite elements, nElements; * 1. the weight of the finite elements, elementArea; * 2. the radius of the finite elements, elementRadius; * 3. the centers of the finite elements, elementCenter; * 4. the normal vectors relative to the centers, elementNormal. * Each of these objects is saved in a separate .npy binary file * and compressed into one .npz file. * Notice that this is just the minimal set of data needed to * restart an energy calculation. */ virtual void saveCavity(const std::string & fname = "cavity.npz"); /*! \brief Load cavity specification from file. */ virtual void loadCavity(const std::string & fname = "cavity.npz"); friend std::ostream & operator<<(std::ostream & os, ICavity & cavity) { return cavity.printCavity(os); } }; } // namespace pcm