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 <string>
27 #include <vector>
28 
29 #include "Config.hpp"
30 #include "PCMSolverExport.h"
31 
32 #include "utils/getkw/Getkw.h"
33 
34 /*! \file Input.hpp */
35 
36 /*! \struct PCMInput
37  */
38 
39 struct PCMInput;
40 
41 namespace pcm {
42 struct BIOperatorData;
43 struct CavityData;
44 struct GreenData;
45 struct SolverData;
46 } // namespace pcm
47 
48 #include "utils/ChargeDistribution.hpp"
49 #include "utils/MMFQ.hpp"
50 #include "utils/Molecule.hpp"
51 #include "utils/Solvent.hpp"
52 #include "utils/Sphere.hpp"
53 
54 namespace pcm {
55 using utils::ChargeDistribution;
56 using utils::MMFQ;
57 using utils::Solvent;
58 using utils::Sphere;
59 
60 /*! \class Input
61  *  \brief A wrapper class for the Getkw Library C++ bindings.
62  *  \author Roberto Di Remigio
63  *  \date 2013
64  *
65  *  An Input object is to be used as the unique point of access to user-provided
66  *input:
67  *   input ---> parsed input (Python script) ---> Input object (contains all the
68  *input data)
69  *  Definition of input parameters is to be done in the Python script and in this
70  *class.
71  *  They must be specified as private data members with public accessor methods
72  *(get-ters).
73  *  Most of the data members are anyway accessed through the input wrapping struct-s
74  *  In general, no mutator methods (set-ters) should be needed, exceptions to this
75  *rule
76  *  should be carefully considered.
77  */
78 class PCMSolver_EXPORT Input {
79 public:
80   /// Default constructor
Input()81   Input() {}
82   /// Constructor from human-readable input file name
83   Input(const std::string & filename);
84   /// Constructor from host input structs
85   Input(const PCMInput & host_input);
86 
87   /// Accessor methods
88 
89   /// Top-level section input
units() const90   std::string units() const { return units_; }
CODATAyear() const91   int CODATAyear() const { return CODATAyear_; }
92   /// @}
93 
94   /// Cavity section input
scaling() const95   bool scaling() const { return scaling_; }
radiiSet() const96   std::string radiiSet() const { return radiiSet_; }
radiiSetName() const97   std::string radiiSetName() const { return radiiSetName_; }
mode() const98   std::string mode() const { return mode_; }
atoms() const99   std::vector<int> atoms() const { return atoms_; }
atoms(size_t i) const100   int atoms(size_t i) const { return atoms_[i]; }
radii() const101   std::vector<double> radii() const { return radii_; }
radii(size_t i) const102   double radii(size_t i) const { return radii_[i]; }
spheres() const103   std::vector<Sphere> spheres() const { return spheres_; }
spheres(int i) const104   Sphere spheres(int i) const { return spheres_[i]; }
molecule() const105   Molecule molecule() const { return molecule_; }
106   /// This method sets the molecule and the list of spheres
molecule(const Molecule & m)107   void molecule(const Molecule & m) {
108     molecule_ = m;
109     spheres_ = molecule_.spheres();
110   }
111   void initMolecule(bool deferred_init = false);
112   /// @}
113 
114   /// Medium section input
solvent() const115   Solvent solvent() const { return solvent_; }
fromSolvent() const116   bool fromSolvent() const { return hasSolvent_; }
correction() const117   double correction() const { return correction_; }
hermitivitize() const118   bool hermitivitize() const { return hermitivitize_; }
isDynamic() const119   bool isDynamic() const { return isDynamic_; }
integratorScaling() const120   double integratorScaling() const { return integratorScaling_; }
isFQ() const121   bool isFQ() const { return isFQ_; }
isNonPolarizable() const122   bool isNonPolarizable() const { return isNonPolarizable_; }
123   /// @}
124 
125   /// Keeps track of who did the parsing: the API or the host program
providedBy() const126   std::string providedBy() const { return providedBy_; }
127 
128   /// Get-ters for input wrapping structs
129   CavityData cavityParams() const;
130   GreenData insideGreenParams() const;
131   GreenData outsideStaticGreenParams() const;
132   GreenData outsideDynamicGreenParams() const;
133   SolverData solverParams() const;
134   BIOperatorData integratorParams() const;
135   /// @}
136 
multipoles() const137   ChargeDistribution multipoles() const { return multipoles_; }
fragments() const138   MMFQ fragments() const { return fragments_; }
MEPfromMolecule()139   bool MEPfromMolecule() { return MEPfromMolecule_; }
MEPfromChargeDistribution()140   bool MEPfromChargeDistribution() { return MEPfromChargeDist_; }
141 
142   /// Operators
143   /// operator<<
144   friend std::ostream & operator<<(std::ostream & os, const Input & input);
145   /// @}
146 private:
147   void reader(const std::string & filename);
148   /*! Read host data structures (host-side syntactic input parsing) into Input
149    * object.
150    *  It provides access to a **limited** number of options only, basically the ones
151    *  that can be filled into the cavityInput, solverInput and greenInput data
152    * structures.
153    *  Lengths and areas are **expected** to be in Angstrom/Angstrom^2 and will hence
154    * be converted
155    *  to au/au^2.
156    *  \note Specification of the solvent by name overrides any input given through
157    * the
158    *  greenInput data structure!
159    *  \warning The cavity can only be built in the "Implicit" mode, i.e. by grabbing
160    * the
161    *  coordinates for the sphere centers from the host program.
162    *  Atomic coordinates are **expected** to be in au!
163    *  The "Atoms" and "Explicit" methods are only available using the explicit
164    * parsing
165    *  by our Python script of a separate input file.
166    */
167   void reader(const PCMInput & host_input);
168   /*! Perform semantic input parsing aka sanity check */
169   void semanticCheck();
170 
171   /// Units of measure
172   std::string units_;
173   /// Year of the CODATA set to be used
174   int CODATAyear_;
175   /// The type of cavity
176   std::string cavityType_;
177   /// Filename for the .npz cavity restart file
178   std::string cavFilename_;
179   /// GePol cavity average element area
180   double area_;
181   /// Whether the radii should be scaled by 1.2
182   bool scaling_;
183   /// The set of radii to be used
184   std::string radiiSet_;
185   /// Collects info on atomic radii set
186   std::string radiiSetName_;
187   /// Minimal radius of an added sphere
188   double minimalRadius_;
189   /// How the API should get the coordinates of the sphere centers
190   std::string mode_;
191   /// List of selected atoms with custom radii
192   std::vector<int> atoms_;
193   /// List of radii attached to the selected atoms
194   std::vector<double> radii_;
195   /// List of spheres for fully custom cavity generation
196   std::vector<Sphere> spheres_;
197   /// Molecule or atomic aggregate
198   Molecule molecule_;
199   /// The solvent for a vacuum/uniform dielectric run
200   Solvent solvent_;
201   /// Whether the medium was initialized from a solvent object
202   bool hasSolvent_;
203   /// The solver type
204   std::string solverType_;
205   /// Correction factor (C-PCM)
206   double correction_;
207   /// Whether the PCM matrix should be hermitivitized (collocation solvers)
208   bool hermitivitize_;
209   /// Whether the dynamic PCM matrix should be used
210   bool isDynamic_;
211   /// Solvent probe radius
212   double probeRadius_;
213   /// Type of integrator for the diagonal of the boundary integral operators
214   std::string integratorType_;
215   /// Scaling factor for the diagonal of the approximate collocation boundary
216   /// integral operators
217   double integratorScaling_;
218   /// The Green's function type inside the cavity.
219   /// It encodes the Green's function type, derivative calculation strategy and
220   /// dielectric profile: TYPE_DERIVATIVE_PROFILE
221   std::string greenInsideType_;
222   /// The Green's function type outside the cavity
223   /// It encodes the Green's function type, derivative calculation strategy and
224   /// dielectric profile: TYPE_DERIVATIVE_PROFILE
225   std::string greenOutsideType_;
226   /// Permittivity inside the cavity
227   double epsilonInside_;
228   /// Static permittivity outside the cavity
229   double epsilonStaticOutside_;
230   /// Dynamic permittivity outside the cavity
231   double epsilonDynamicOutside_;
232   /// Diffuse interface: static permittivity inside the interface
233   double epsilonStatic1_;
234   /// Diffuse interface: dynamic permittivity inside the interface
235   double epsilonDynamic1_;
236   /// Diffuse interface: static permittivity outside the interface
237   double epsilonStatic2_;
238   /// Diffuse interface: dynamic permittivity outside the interface
239   double epsilonDynamic2_;
240   /// Center of the diffuse interface
241   double center_;
242   /// Width of the diffuse interface
243   double width_;
244   /// Maximum angular momentum
245   int maxL_;
246   /// Center of the dielectric sphere
247   std::vector<double> origin_;
248   /// Molecular geometry
249   std::vector<double> geometry_;
250   /// Whether this is a FQ calculation
251   bool isFQ_;
252   /// Whether this is a nonpolarizable MM calculation
253   bool isNonPolarizable_;
254   /// Whether to calculate the MEP from the molecular geometry
255   bool MEPfromMolecule_;
256   /// Whether to calculate the MEP from the charge distribution
257   bool MEPfromChargeDist_;
258   /// Classical charge distribution of point multipoles
259   ChargeDistribution multipoles_;
260   /// Classical fluctuating charges MM force field
261   MMFQ fragments_;
262   /// Who performed the syntactic input parsing
263   std::string providedBy_;
264 };
265 
266 namespace detail {
267 std::string left_trim(std::string s);
268 std::string left_trim(const char * src);
269 
270 std::string right_trim(std::string s);
271 std::string right_trim(const char * src);
272 
273 std::string trim(std::string s);
274 std::string trim(const char * src);
275 
276 std::string uppercase(std::string s);
277 std::string uppercase(const char * src);
278 
279 std::string trim_and_upper(const char * src);
280 
281 enum PCMInputFields {
282   cavity_type,
283   patch_level,
284   coarsity,
285   area,
286   radii_set,
287   min_distance,
288   der_order,
289   scaling,
290   restart_name,
291   min_radius,
292   solver_type,
293   correction,
294   solvent,
295   probe_radius,
296   equation_type,
297   inside_type,
298   outside_epsilon,
299   outside_type
300 };
301 
302 PCMInputFields string_to_enum(std::string field);
303 } // namespace detail
304 } // namespace pcm
305