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