1 /*
2  *                This source code is part of
3  *
4  *                     E  R  K  A  L  E
5  *                             -
6  *                       HF/DFT from Hel
7  *
8  * Written by Susi Lehtola, 2010-2011
9  * Copyright (c) 2010-2011, Susi Lehtola
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  */
16 
17 #include <cstdio>
18 #include "optimize_completeness.h"
19 #include "../basislibrary.h"
20 #include "../global.h"
21 #include "../timer.h"
22 #include "../settings.h"
23 
24 #ifdef _OPENMP
25 #include <omp.h>
26 #endif
27 
28 #ifdef SVNRELEASE
29 #include "../version.h"
30 #endif
31 
32 Settings settings;
33 
main_guarded(int argc,char ** argv)34 int main_guarded(int argc, char **argv) {
35 #ifdef _OPENMP
36   printf("ERKALE - Completeness optimization from Hel. OpenMP version, running on %i cores.\n",omp_get_max_threads());
37 #else
38   printf("ERKALE - Completeness optimization from Hel. Serial version.\n");
39 #endif
40   print_copyright();
41   print_license();
42 #ifdef SVNRELEASE
43   printf("At svn revision %s.\n\n",SVNREVISION);
44 #endif
45   print_hostname();
46 
47   settings.add_int("am","angular momentum of shell to optimize for",0);
48   settings.add_int("n","moment to optimize for: 1 for maximal area, 2 for minimal rms deviation",1);
49   settings.add_double("min","lower limit of exponent range in log10",-2,true);
50   settings.add_double("tol","the tolerance to target in the optimization",1e-3);
51   settings.add_int("nfunc","Fixed number of functions to optimize",0);
52   settings.add_int("nfull","Number of functions at each side to fully optimize",4);
53   settings.add_bool("coulomb","Use Coulomb metric? (Use only for RI basis sets)",false);
54   settings.add_double("LinDepThresh","Basis set linear dependence threshold",1e-5);
55   settings.add_string("Output","Output file to use","optimized.gbs");
56 
57   if(argc!=2) {
58     settings.print();
59     printf("Usage: %s runfile\n",argv[0]);
60     return 1;
61   }
62   settings.parse(std::string(argv[1]),true);
63   settings.print();
64 
65   // Get parameters
66   int am=settings.get_int("am");
67   int n=settings.get_int("n");
68   double min=settings.get_double("min");
69 
70   // Did we get a tolerance, or a number of functions?
71   double tol=settings.get_double("tol");
72   int nfunc=settings.get_int("nfunc");
73   int nfull=settings.get_int("nfull");
74   bool coulomb=settings.get_bool("coulomb");
75   // The Coulomb metric is equivalent to the normal metric with am-1
76   if(coulomb)
77     am--;
78 
79   Timer t;
80 
81   // Form optimized set of primitives
82   double w;
83   arma::vec exps=move_exps(maxwidth_exps(am,tol,nfunc,w,n,nfull),min);
84 
85   // Return the original value if Coulomb metric was used
86   if(coulomb)
87     am++;
88 
89   // Create a basis set out of it. Print exponents in descending order
90   ElementBasisSet el("El");
91   for(size_t i=exps.size()-1;i<exps.size();i--) {
92     // Create shell of functions
93     FunctionShell tmp(am);
94     tmp.add_exponent(1.0,exps[i]);
95     // and add it to the basis set
96     el.add_function(tmp);
97   }
98 
99   BasisSetLibrary baslib;
100   baslib.add_element(el);
101   baslib.save_gaussian94(settings.get_string("Output"));
102 
103   printf("Optimization performed in %s.\n",t.elapsed().c_str());
104   printf("\nCompleteness-optimized basis set saved to %s.\n",settings.get_string("Output").c_str());
105 
106   printf("Width of profile is %.10e.\n",w);
107 
108   return 0;
109 }
110 
main(int argc,char ** argv)111 int main(int argc, char **argv) {
112   try {
113     return main_guarded(argc, argv);
114   } catch (const std::exception &e) {
115     std::cerr << "error: " << e.what() << std::endl;
116     return 1;
117   }
118 }
119