1 /*
2  * PCMSolver, an API for the Polarizable Continuum Model
3  * Copyright (C) 2020 Roberto Di Remigio, Luca Frediani and contributors.
4  *
5  * This file is part of PCMSolver.
6  *
7  * PCMSolver is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * PCMSolver is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with PCMSolver.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  * For information on the complete list of contributors to the
21  * PCMSolver API, see: <http://pcmsolver.readthedocs.io/>
22  */
23 
24 #pragma once
25 
26 #include <iosfwd>
27 #include <string>
28 #include <vector>
29 
30 #include "Config.hpp"
31 
32 #include <Eigen/Core>
33 
34 /*! \file CPCMSolver.hpp */
35 
36 namespace pcm {
37 class ICavity;
38 class IGreensFunction;
39 class IBoundaryIntegralOperator;
40 struct SolverData;
41 } // namespace pcm
42 
43 #include "ISolver.hpp"
44 
45 namespace pcm {
46 namespace solver {
47 /*! \class CPCMSolver
48  *  \brief Solver for conductor-like approximation: C-PCM (COSMO)
49  *  \author Roberto Di Remigio
50  *  \date 2013, 2016
51  *
52  *  \note We store the scaled, Hermitian, symmetrized S matrix and use a robust
53  *  Cholesky decomposition to solve for the ASC.
54  *  This avoids computing and storing the inverse explicitly.
55  *  The S matrix is already scaled by the dielectric factor entering the
56  *  definition of the conductor model!
57  */
58 class CPCMSolver : public ISolver {
59 public:
CPCMSolver()60   CPCMSolver() {}
61   /*! \brief Construct solver
62    *  \param[in] symm whether the system matrix has to be symmetrized
63    *  \param[in] corr factor to correct the conductor results
64    */
CPCMSolver(bool symm,double corr)65   CPCMSolver(bool symm, double corr)
66       : ISolver(), hermitivitize_(symm), correction_(corr) {}
67 
68 private:
69   /*! Whether the system matrix has to be symmetrized */
70   bool hermitivitize_;
71   /*! Correction for the conductor results */
72   double correction_;
73   /*! S matrix, not symmetry blocked */
74   Eigen::MatrixXd S_;
75   /*! S matrix, symmetry blocked form */
76   std::vector<Eigen::MatrixXd> blockS_;
77 
78   /*! \brief Calculation of the PCM matrix
79    *  \param[in] cavity the cavity to be used
80    *  \param[in] gf_i Green's function inside the cavity
81    *  \param[in] gf_o Green's function outside the cavity
82    *  \param[in] op integrator strategy for the single layer operator
83    */
84   virtual void buildSystemMatrix_impl(const ICavity & cavity,
85                                       const IGreensFunction & gf_i,
86                                       const IGreensFunction & gf_o,
87                                       const IBoundaryIntegralOperator & op) override;
88   /*! \brief Returns the ASC given the MEP and the desired irreducible representation
89    *  \param[in] potential the vector containing the MEP at cavity points
90    *  \param[in] irrep the irreducible representation of the MEP and ASC
91    */
92   virtual Eigen::VectorXd computeCharge_impl(const Eigen::VectorXd & potential,
93                                              int irrep = 0) const override;
94   virtual std::ostream & printSolver(std::ostream & os) override;
95 };
96 
97 ISolver * createCPCMSolver(const SolverData & data);
98 } // namespace solver
99 } // namespace pcm
100