Scine::Sparrow  5.0.0
Library for fast and agile quantum chemical calculations with semiempirical methods.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
SpectroscopySettings.h
Go to the documentation of this file.
1 
7 #ifndef SPARROW_SPECTROSCOPYSETTINGS_H
8 #define SPARROW_SPECTROSCOPYSETTINGS_H
9 
13 #include <Utils/Settings.h>
18 #include <cassert>
19 
20 namespace Scine {
21 namespace Sparrow {
22 namespace RealTimeSpectroscopy {
23 
24 constexpr const char* resolutionOption = "spectrum_resolution";
25 constexpr const char* fwhmOption = "spectrum_fwhm";
26 constexpr const char* gradientThresholdOption = "gradient_threshold";
27 constexpr const char* partialHessianOption = "partial_hessian";
28 constexpr const char* projectionOption = "gradient_projection";
29 constexpr const char* partialHessianRMSDDeviationOption = "partial_hessian_RMSD_deviation";
30 constexpr const char* uvVisGuessPropagatorDiisDimension = "uv_vis_diis_max_dimension";
31 constexpr const char* optimizationProfileOption = "optimization_profile";
32 
34  public:
35  SpectroscopySettings() : Utils::Settings("Spectroscopy Settings") {
36  }
37  explicit SpectroscopySettings(std::string settingName) : Utils::Settings(std::move(settingName)) {
38  resetToDefaults();
39  }
40 
41  protected:
42  void addResolutionOption(double minValue, double maxValue, double defaultValue) {
43  assert(minValue < maxValue && "Min value must be smaller than max value.");
44  assert(minValue < defaultValue && "Min value must be smaller than default value.");
45  assert(defaultValue < maxValue && "default value must be smaller than max value.");
46  Utils::UniversalSettings::DoubleDescriptor resolution("The resolution the spectrum should have."
47  "For IR, this is in cm^-1, for UV/Vis in eV.");
48  resolution.setMinimum(minValue);
49  resolution.setMaximum(maxValue);
50  resolution.setDefaultValue(defaultValue);
51  _fields.push_back(resolutionOption, std::move(resolution));
52  }
53  void addFWHMOption(double defaultFwhm) {
54  assert(defaultFwhm < 100. && "Min value must be smaller than default value.");
55  assert(defaultFwhm > 0. && "default value must be smaller than max value.");
56  Utils::UniversalSettings::DoubleDescriptor fwhm("The fwhm of the peaks in the spectrum."
57  "For IR, this is in cm^-1, for UV/Vis in eV.");
58  fwhm.setMinimum(0.);
59  fwhm.setMaximum(100.);
60  fwhm.setDefaultValue(defaultFwhm);
61  _fields.push_back(fwhmOption, std::move(fwhm));
62  }
63  void addMethodOption() {
64  Utils::UniversalSettings::StringDescriptor parameterFile("Path to the parameter file");
65  parameterFile.setDefaultValue("");
66  _fields.push_back(Utils::SettingsNames::methodParameters, std::move(parameterFile));
67 
68  Utils::UniversalSettings::StringDescriptor method("The method used in the digester.");
69  method.setDefaultValue("PM6");
70  _fields.push_back(Utils::SettingsNames::method, std::move(method));
71 
73  }
74  void addPruningOption() {
76  "Sets whether the basis of singly excited determinants should be pruned and with which method.");
77  prunedBasisCalculation.addOption(Utils::SettingsNames::PruningOptions::none);
78  prunedBasisCalculation.addOption(Utils::SettingsNames::PruningOptions::energy);
79  prunedBasisCalculation.setDefaultOption(Utils::SettingsNames::PruningOptions::none);
80 
81  Utils::UniversalSettings::DoubleDescriptor energyThresholdForPruning(
82  "Sets the threshold for pruning with an energy criterion in au.");
83  energyThresholdForPruning.setMinimum(0.0);
84  energyThresholdForPruning.setDefaultValue(0.0);
85 
86  Utils::UniversalSettings::DoubleDescriptor perturbationTheoryThresholdForPruning(
87  "Sets the threshold for pruning with an intensity criterion in au.");
88  perturbationTheoryThresholdForPruning.setMinimum(0.);
89  perturbationTheoryThresholdForPruning.setDefaultValue(1e-4);
90 
92  "Switches on the TDA for the excited states calculation.");
93  TDAApproximation.setDefaultValue(false);
94 
95  _fields.push_back(Utils::SettingsNames::pruneBasis, std::move(prunedBasisCalculation));
96  _fields.push_back(Utils::SettingsNames::energyThreshold, std::move(energyThresholdForPruning));
97  _fields.push_back(Utils::SettingsNames::perturbativeThreshold, std::move(perturbationTheoryThresholdForPruning));
98  _fields.push_back("tda", std::move(TDAApproximation));
99  }
100 };
101 
103  public:
104  IRSettings() : SpectroscopySettings("IR Settings") {
105  addResolutionOption(0.1, 10, 1);
106  addFWHMOption(30.);
107  addMethodOption();
108 
109  Utils::UniversalSettings::BoolDescriptor gradientProjection("Flags the use of the gradient projection technique.");
110  _fields.push_back(projectionOption, std::move(gradientProjection));
111 
113  "How tight the structure is optimized before projection. VeryTight, Tight, Medium, Loose, VeryLoose.");
114  optimizationProfile.addOption("very_tight");
115  optimizationProfile.addOption("tight");
116  optimizationProfile.addOption("medium");
117  optimizationProfile.addOption("loose");
118  optimizationProfile.addOption("very_loose");
119  optimizationProfile.addOption("none");
120  optimizationProfile.setDefaultOption("tight");
121 
122  _fields.push_back(optimizationProfileOption, std::move(optimizationProfile));
123 
124  Utils::UniversalSettings::DoubleDescriptor gradientThreshold("The gradient threshold for minima detection (au).");
125  gradientThreshold.setMinimum(1.0e-4);
126  gradientThreshold.setMaximum(1.0);
127  gradientThreshold.setDefaultValue(1.0e-2);
128 
129  _fields.push_back(gradientThresholdOption, std::move(gradientThreshold));
130 
131  Utils::UniversalSettings::BoolDescriptor partialHessianCalculation(
132  "Calculate only parts of the Hessian matrix corresponding"
133  "to atoms that moved consistently wrt last calculation.");
134  partialHessianCalculation.setDefaultValue(false);
135  _fields.push_back(partialHessianOption, std::move(partialHessianCalculation));
136 
138  "Deviation atoms in aligned structures must have to be"
139  "considered diverging.");
140  partialHessianRMSD.setMinimum(1.0e-2);
141  partialHessianRMSD.setMaximum(1.0);
142  partialHessianRMSD.setDefaultValue(0.2);
143 
144  _fields.push_back(partialHessianRMSDDeviationOption, std::move(partialHessianRMSD));
145 
146  resetToDefaults();
147  }
148 };
150  public:
151  UvVisSettings() : SpectroscopySettings("Uv/Vis Settings") {
152  addResolutionOption(0.0001, 0.3, 0.002);
153  addFWHMOption(0.3);
154  addMethodOption();
155  addPruningOption();
156 
157  Utils::UniversalSettings::IntDescriptor numberEigenvalues("Number of roots to be calculated");
158  numberEigenvalues.setMinimum(1);
159  numberEigenvalues.setDefaultValue(20);
160  _fields.push_back(Utils::SettingsNames::numberOfEigenstates, std::move(numberEigenvalues));
161 
162  Utils::UniversalSettings::IntDescriptor initialSubspaceDimension("Dimension of the guess subspace");
163  numberEigenvalues.setMinimum(1);
164  numberEigenvalues.setDefaultValue(1);
165  _fields.push_back(Utils::SettingsNames::initialSubspaceDimension, std::move(initialSubspaceDimension));
166 
168  "Algorithm to compute the stable generalized eigenvalue problem.");
169  gepAlgorithm.addOption("standard");
170  gepAlgorithm.addOption("cholesky");
171  gepAlgorithm.addOption("simultaneous_diag");
172  gepAlgorithm.setDefaultOption("simultaneous_diag");
173  _fields.push_back("gep_algo", std::move(gepAlgorithm));
174 
175  Utils::UniversalSettings::IntDescriptor maxDiisDimension("Maximal dimension of the diis subspace");
176  maxDiisDimension.setMinimum(1);
177  maxDiisDimension.setDefaultValue(4);
178  _fields.push_back(uvVisGuessPropagatorDiisDimension, std::move(maxDiisDimension));
179 
180  resetToDefaults();
181  }
182 };
183 
185  GeometryOptimizationProfile(Utils::Settings settings) : settings_(std::move(settings)) {
186  }
187  virtual ~GeometryOptimizationProfile() = default;
188  Utils::Settings toSettings() {
189  applyProfile(settings_);
190  return settings_;
191  }
192  virtual void applyProfile(Utils::Settings& settings) = 0;
193 
194  private:
195  Utils::Settings settings_;
196 };
197 
200  ~VeryTightOptimizationProfile() final = default;
201  void applyProfile(Utils::Settings& settings) final {
202  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::stepMaxCoeff, 2.0e-5);
203  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::stepRMS, 1.0e-5);
204  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::gradMaxCoeff, 2.0e-5);
205  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::gradRMS, 1.0e-5);
206  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::deltaValue, 1.0e-7);
207  settings.modifyInt(Utils::SettingsNames::Optimizations::Convergence::maxIter, 1000);
208  settings.modifyInt(Utils::SettingsNames::Optimizations::Convergence::requirement, 4);
209  settings.modifyInt(Utils::SettingsNames::Optimizations::Bfgs::gdiisMaxStore, 10);
210  }
211 };
214  ~TightOptimizationProfile() final = default;
215  void applyProfile(Utils::Settings& settings) final {
216  settings.modifyInt(Utils::SettingsNames::Optimizations::Bfgs::gdiisMaxStore, 8);
217  settings.modifyInt(Utils::SettingsNames::Optimizations::Convergence::maxIter, 1000);
218  }
219 };
222  ~MediumOptimizationProfile() final = default;
223  void applyProfile(Utils::Settings& settings) final {
224  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::stepMaxCoeff, 5.0e-4);
225  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::stepRMS, 5.0e-3);
226  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::gradMaxCoeff, 5.0e-4);
227  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::gradRMS, 5.0e-4);
228  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::deltaValue, 5.0e-6);
229  settings.modifyInt(Utils::SettingsNames::Optimizations::Convergence::maxIter, 100);
230  settings.modifyInt(Utils::SettingsNames::Optimizations::Convergence::requirement, 2);
231  settings.modifyInt(Utils::SettingsNames::Optimizations::Bfgs::gdiisMaxStore, 8);
232  }
233 };
236  ~LooseOptimizationProfile() final = default;
237  void applyProfile(Utils::Settings& settings) final {
238  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::stepMaxCoeff, 5.0e-3);
239  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::stepRMS, 1.0e-2);
240  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::gradMaxCoeff, 1.0e-3);
241  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::gradRMS, 5.0e-3);
242  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::deltaValue, 1.0e-5);
243  settings.modifyInt(Utils::SettingsNames::Optimizations::Convergence::maxIter, 100);
244  settings.modifyInt(Utils::SettingsNames::Optimizations::Convergence::requirement, 2);
245  settings.modifyInt(Utils::SettingsNames::Optimizations::Bfgs::gdiisMaxStore, 8);
246  }
247 };
250  ~VeryLooseOptimizationProfile() final = default;
251  void applyProfile(Utils::Settings& settings) final {
252  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::stepMaxCoeff, 1.0e-2);
253  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::stepRMS, 5.0e-2);
254  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::gradMaxCoeff, 5.0e-3);
255  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::gradRMS, 1.0e-2);
256  settings.modifyDouble(Utils::SettingsNames::Optimizations::Convergence::deltaValue, 1.0e-4);
257  settings.modifyInt(Utils::SettingsNames::Optimizations::Convergence::maxIter, 50);
258  settings.modifyInt(Utils::SettingsNames::Optimizations::Convergence::requirement, 2);
259  settings.modifyInt(Utils::SettingsNames::Optimizations::Bfgs::gdiisMaxStore, 8);
260  }
261 };
262 
263 inline std::unique_ptr<GeometryOptimizationProfile> profileFactory(const Utils::Settings& settings, const std::string& profile) {
264  if (profile == "very_tight")
265  return std::make_unique<VeryTightOptimizationProfile>(settings);
266  else if (profile == "tight")
267  return std::make_unique<TightOptimizationProfile>(settings);
268  else if (profile == "medium")
269  return std::make_unique<MediumOptimizationProfile>(settings);
270  else if (profile == "loose")
271  return std::make_unique<LooseOptimizationProfile>(settings);
272  else if (profile == "very_loose")
273  return std::make_unique<VeryLooseOptimizationProfile>(settings);
274  else
275  throw std::runtime_error("Geometry optimization profile '" + profile +
276  "' not found."
277  "Possible profiles: very_tight, tight, medium, loose, very_loose");
278 }
279 
280 } // namespace RealTimeSpectroscopy
281 } // namespace Sparrow
282 } // namespace Scine
283 
284 #endif // SPARROW_SPECTROSCOPYSETTINGS_H
static void populateScfSettings(SettingsCollection &settings)
Definition: SpectroscopySettings.h:149
Definition: SpectroscopySettings.h:102