| 1 | /*
 | 
|---|
| 2 |  * PartialNucleiChargeFitter.hpp
 | 
|---|
| 3 |  *
 | 
|---|
| 4 |  *  Created on: 12.05.2013
 | 
|---|
| 5 |  *      Author: heber
 | 
|---|
| 6 |  */
 | 
|---|
| 7 | 
 | 
|---|
| 8 | #ifndef PARTIALNUCLEICHARGEFITTER_HPP_
 | 
|---|
| 9 | #define PARTIALNUCLEICHARGEFITTER_HPP_
 | 
|---|
| 10 | 
 | 
|---|
| 11 | // include config.h
 | 
|---|
| 12 | #ifdef HAVE_CONFIG_H
 | 
|---|
| 13 | #include <config.h>
 | 
|---|
| 14 | #endif
 | 
|---|
| 15 | 
 | 
|---|
| 16 | #include <vector>
 | 
|---|
| 17 | 
 | 
|---|
| 18 | #include "LinearAlgebra/Vector.hpp"
 | 
|---|
| 19 | #include "LinearAlgebra/VectorContent.hpp"
 | 
|---|
| 20 | 
 | 
|---|
| 21 | #include "Fragmentation/Summation/SetValues/SamplingGridProperties.hpp"
 | 
|---|
| 22 | 
 | 
|---|
| 23 | class PartialNucleiChargeFitterTest;
 | 
|---|
| 24 | class SamplingGrid;
 | 
|---|
| 25 | 
 | 
|---|
| 26 | /** This class is a functor that fits the magnitudes of a give number of
 | 
|---|
| 27 |  * point charges to a sampled electrostatic potential distribution by
 | 
|---|
| 28 |  * solving an over-determined system of equations.
 | 
|---|
| 29 |  *
 | 
|---|
| 30 |  * We require thus a sampled potential and the spatial positions of the
 | 
|---|
| 31 |  * charges. As a result we offer the partial point charge at each position.
 | 
|---|
| 32 |  *
 | 
|---|
| 33 |  * Note that we fit to the potential of both nuclei and electrons.
 | 
|---|
| 34 |  * And also note that open boundary conditions should be used as we compare
 | 
|---|
| 35 |  * to the potential of spherical point charges and we do not do any Wolf
 | 
|---|
| 36 |  * or Ewald summation.
 | 
|---|
| 37 |  */
 | 
|---|
| 38 | class PartialNucleiChargeFitter
 | 
|---|
| 39 | {
 | 
|---|
| 40 |   //!> grant unit test access to private parts.
 | 
|---|
| 41 |   friend class PartialNucleiChargeFitterTest;
 | 
|---|
| 42 | public:
 | 
|---|
| 43 |   //!> typedef for the charge type to fit
 | 
|---|
| 44 |   typedef double charge_t;
 | 
|---|
| 45 |   //!> typedef for the number of charges to fit at the same time
 | 
|---|
| 46 |   typedef std::vector<charge_t> charges_t;
 | 
|---|
| 47 |   //!> typedef for specifying a position in 3D
 | 
|---|
| 48 |   typedef Vector position_t;
 | 
|---|
| 49 |   //!> typedef for specifying positions of all nuclei whose charges to fit
 | 
|---|
| 50 |   typedef std::vector< position_t > positions_t;
 | 
|---|
| 51 |   typedef size_t dimension_t;
 | 
|---|
| 52 |   typedef std::vector<dimension_t> dimensions_t;
 | 
|---|
| 53 | 
 | 
|---|
| 54 |   /** Constructor for class PartialNucleiChargeFitter.
 | 
|---|
| 55 |    *
 | 
|---|
| 56 |    * \note Copies given parameters as it does not impact on overall
 | 
|---|
| 57 |    * performance significantly.
 | 
|---|
| 58 |    *
 | 
|---|
| 59 |    * \warning the \a threshold parameter is important! Core electrons are very
 | 
|---|
| 60 |    * strongly localized and can in the general case not be properly sampled on
 | 
|---|
| 61 |    * a grid. As for the partial charges we are not interested in modelling the
 | 
|---|
| 62 |    * potential around the nuclei but around the molecule as a whole, with this
 | 
|---|
| 63 |    * parameter the inner potential is masked and excluded from the fit. This does
 | 
|---|
| 64 |    * not mask any charge, it just avoids the strongly peaked electrons along with
 | 
|---|
| 65 |    * "in short-range falsely" smeared-out nuclei charges. We recommend a value of
 | 
|---|
| 66 |    * e.\,g. 1 or more. This should stabilize of finer grids and larger thresholds.
 | 
|---|
| 67 |    *
 | 
|---|
| 68 |    * \param grid grid with sampled (long-range) potential to match
 | 
|---|
| 69 |    * \param _positions vector of positions
 | 
|---|
| 70 |    * \param _threshold radius of spherical mask around nuclei
 | 
|---|
| 71 |    */
 | 
|---|
| 72 |   PartialNucleiChargeFitter(
 | 
|---|
| 73 |       const SamplingGrid &grid,
 | 
|---|
| 74 |       const positions_t &_positions,
 | 
|---|
| 75 |       const double _threshold = 0.);
 | 
|---|
| 76 | 
 | 
|---|
| 77 |   /** Destructor for class PartialNucleiChargeFitter.
 | 
|---|
| 78 |    *
 | 
|---|
| 79 |    */
 | 
|---|
| 80 |    ~PartialNucleiChargeFitter();
 | 
|---|
| 81 | 
 | 
|---|
| 82 |    /** Function to evaluate the over-determined system given by the
 | 
|---|
| 83 |     * desired sampled potential and a number of charges at given positions.
 | 
|---|
| 84 |     *
 | 
|---|
| 85 |     * \return L_2-Fehler des Residuums (Ax-b)
 | 
|---|
| 86 |     */
 | 
|---|
| 87 |    double operator()();
 | 
|---|
| 88 | 
 | 
|---|
| 89 |    /** Getter for the problem matrix A.
 | 
|---|
| 90 |     *
 | 
|---|
| 91 |     * The matrix represents the sampled potential per charge/column vector
 | 
|---|
| 92 |     * with unit charge.
 | 
|---|
| 93 |     *
 | 
|---|
| 94 |     * \return matrix A in system Ax=b or NLL if not constructed yet.
 | 
|---|
| 95 |     */
 | 
|---|
| 96 |    const MatrixContent &getMatrix() const
 | 
|---|
| 97 |    {
 | 
|---|
| 98 |      return *PotentialFromCharges;
 | 
|---|
| 99 |    }
 | 
|---|
| 100 | 
 | 
|---|
| 101 |    /** Getter for solution as charges_t
 | 
|---|
| 102 |     *
 | 
|---|
| 103 |     * \return solution vector x as type charges_t
 | 
|---|
| 104 |     */
 | 
|---|
| 105 |    charges_t getSolutionAsCharges_t() const;
 | 
|---|
| 106 | 
 | 
|---|
| 107 |    void writeMatrix();
 | 
|---|
| 108 | 
 | 
|---|
| 109 | private:
 | 
|---|
| 110 |    /** Helper function to construct the problem Matrix A.
 | 
|---|
| 111 |     *
 | 
|---|
| 112 |     */
 | 
|---|
| 113 |    void constructMatrix();
 | 
|---|
| 114 | 
 | 
|---|
| 115 |    /** Internal function to calculate the discrete grid dimension per axis.
 | 
|---|
| 116 |     *
 | 
|---|
| 117 |     * \param grid grid whose dimensions are to be determind
 | 
|---|
| 118 |     * \return vector of 3 grid dimensions
 | 
|---|
| 119 |     */
 | 
|---|
| 120 |    dimensions_t getGridDimensions(const SamplingGrid &grid) const;
 | 
|---|
| 121 | 
 | 
|---|
| 122 |    /** Helper function to mask out regions around nuclei.
 | 
|---|
| 123 |     *
 | 
|---|
| 124 |     * The electronic potential is too peaked around the nuclei, i.e.
 | 
|---|
| 125 |     * cannot be sanely modelled by the partial point charges. Hence,
 | 
|---|
| 126 |     * we mask out these regions
 | 
|---|
| 127 |     *
 | 
|---|
| 128 |     * \return true - point is at least threshold away from any nuclei, false - else
 | 
|---|
| 129 |     */
 | 
|---|
| 130 |    bool isGridPointSettable(
 | 
|---|
| 131 |        const positions_t &_positions,
 | 
|---|
| 132 |        const Vector &grid_position) const;
 | 
|---|
| 133 | 
 | 
|---|
| 134 | private:
 | 
|---|
| 135 |    //!> grid dimensions per axis for internal use
 | 
|---|
| 136 |    const dimensions_t total;
 | 
|---|
| 137 |    //!> sampled potential as right hand side for Ax=b
 | 
|---|
| 138 |    const VectorContent SampledPotential;
 | 
|---|
| 139 |    //!> properties of grid for calculating potential on same grid
 | 
|---|
| 140 |    const SamplingGridProperties grid_properties;
 | 
|---|
| 141 |    //!> positions of nuclei whose charges are to be fitted
 | 
|---|
| 142 |    const positions_t positions;
 | 
|---|
| 143 |    //!> internal matrix representing potential by spherical charges (we use MatrixContent as there is only a 3x3 RealSpaceMatrix, no generic one)
 | 
|---|
| 144 |    MatrixContent *PotentialFromCharges;
 | 
|---|
| 145 |    //!> internal representation of solution vector x
 | 
|---|
| 146 |    VectorContent *PartialCharges;
 | 
|---|
| 147 |    //!> threshold for minimum distance to any nuclei in fitting
 | 
|---|
| 148 |    const double threshold;
 | 
|---|
| 149 | };
 | 
|---|
| 150 | 
 | 
|---|
| 151 | #endif /* PARTIALNUCLEICHARGEFITTER_HPP_ */
 | 
|---|