1 /* Ergo, version 3.8, a program for linear scaling electronic structure
2 * calculations.
3 * Copyright (C) 2019 Elias Rudberg, Emanuel H. Rubensson, Pawel Salek,
4 * and Anastasia Kruchinina.
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Primary academic reference:
20 * Ergo: An open-source program for linear-scaling electronic structure
21 * calculations,
22 * Elias Rudberg, Emanuel H. Rubensson, Pawel Salek, and Anastasia
23 * Kruchinina,
24 * SoftwareX 7, 107 (2018),
25 * <http://dx.doi.org/10.1016/j.softx.2018.03.005>
26 *
27 * For further information about Ergo, see <http://www.ergoscf.org>.
28 */
29
30 /*-*-mode: C; c-indentation-style: "bsd"; c-basic-offset: 4; -*-*/
31 /** @file functionals.c General functional selection and input processing.
32 (c) Pawel Salek, pawsa@theochem.kth.se, 2001-08-02
33
34 */
35
36 #include <stdarg.h>
37 #include <stddef.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <stdlib.h>
41 #define __CVERSION__
42
43 #include "functionals.h"
44
45 Functional* available_functionals[] = {
46 /* generic functionals */
47 &BeckeFunctional,
48 &KTFunctional,
49 &LB94Functional,
50 &LYPFunctional,
51 &OPTXFunctional,
52 &P86cFunctional,
53 &PW86xFunctional,
54 &Pw91xFunctional,
55 &Pw91cFunctional,
56 &PW92cFunctional,
57 &PZ81Functional,
58 &PbecFunctional,
59 &PbexFunctional,
60 &SlaterFunctional,
61 &VWN3Functional,
62 &VWN5Functional,
63 &VWNIFunctional,
64 &VWN3IFunctional,
65 &VWNFunctional,
66 &XAlphaFunctional,
67 /* mixed functionals */
68 &B3LYPFunctional,
69 &B3LYPGaussFunctional,
70 &B3P86Functional,
71 &B3P86GFunctional,
72 &B3PW91Functional,
73 &BHandHFunctional,
74 &BHandHLYPFunctional,
75 &BLYPFunctional,
76 &BP86Functional,
77 &BPW91Functional,
78 &Camb3lypFunctional,
79 &CamFunctional,
80 &CombineFunctional,
81 &GGAKeyFunctional,
82 &HseFunctional,
83 &KT1Functional,
84 &KT2Functional,
85 &KT3Functional,
86 &LDAFunctional,
87 &OLYPFunctional,
88 &PBE0Functional,
89 &PBEFunctional,
90 &SVWN3Functional,
91 &SVWN5Functional,
92 NULL
93 };
94
my_printf(const char * fmt,...)95 static int my_printf(const char *fmt, ...)
96 {
97 int i;va_list ap; va_start(ap, fmt); i= vprintf(fmt, ap); va_end(ap);
98 puts("");
99 return i;
100 }
101
set_hf_weight(real w)102 static void set_hf_weight(real w) {}
get_hf_weight(void)103 static real get_hf_weight(void) {return 0;}
set_cam_param(real w,real b)104 static void set_cam_param(real w, real b) {}
105
106 Functional* selected_func = &LDAFunctional;
107 int (*fun_printf)(const char *fmt, ...) = my_printf;
108 void (*fun_set_hf_weight)(real w) = set_hf_weight;
109 real (*fun_get_hf_weight)(void) = get_hf_weight;
110 void (*fun_set_cam_param)(real w, real b) = set_cam_param;
111
112 /* =================================================================== */
113 enum FunError
fun_select_by_name(const char * conf_string)114 fun_select_by_name(const char *conf_string)
115 {
116 int ok, i;
117 char func_name[40];
118
119 sscanf(conf_string,"%39s", func_name);
120 for(i=0; available_functionals[i]; i++)
121 if(strcasecmp(available_functionals[i]->name, func_name)==0) {
122 selected_func = available_functionals[i];
123 ok = selected_func->read ?
124 selected_func->read(conf_string+strlen(func_name)) : 1;
125 return ok ? FUN_OK : FUN_CONF_ERROR;
126 }
127 return FUN_UNKNOWN;
128 }
129
130 void
drv1_clear(FunFirstFuncDrv * gga)131 drv1_clear(FunFirstFuncDrv* gga)
132 {
133 memset(gga, 0, sizeof(*gga));
134 }
135
136 void
drv2_clear(FunSecondFuncDrv * gga)137 drv2_clear(FunSecondFuncDrv* gga)
138 {
139 memset(gga, 0, sizeof(*gga));
140 }
141
142 void
drv3_clear(FunThirdFuncDrv * gga)143 drv3_clear(FunThirdFuncDrv* gga)
144 {
145 memset(gga, 0, sizeof(*gga));
146 }
147 void
drv4_clear(FunFourthFuncDrv * gga)148 drv4_clear(FunFourthFuncDrv* gga)
149 {
150 memset(gga, 0, sizeof(*gga));
151 }
152
fun_true(void)153 int fun_true(void) { return 1; }
fun_false(void)154 int fun_false(void) { return 0; }
155
156 /* =================================================================== */
157 /* fortran (and not only) functional stub routines */
158 /* =================================================================== */
159
160 /** dftreport:
161 report the selected functional and its configuration.
162 */
163 void
dftreport_(void)164 dftreport_(void)
165 {
166 fun_printf(" This is a DFT calculation of type: %s",
167 selected_func->name);
168 if(selected_func->report)
169 selected_func->report();
170 }
171
172 void
dftlistfuncs_(void)173 dftlistfuncs_(void)
174 {
175 int i;
176 fun_printf("\nAvailable functionals:");
177 for(i=0; available_functionals[i]; i++)
178 fun_printf(available_functionals[i]->name);
179 }
180
181 void
dftlistfuncs_using_printf_(void)182 dftlistfuncs_using_printf_(void)
183 {
184 int i;
185 printf("\nAvailable functionals:\n");
186 for(i=0; available_functionals[i]; i++)
187 printf("%s\n", available_functionals[i]->name);
188 }
189
190 /* declare both known fortran name-mangled variants */
191 int
dft_isgga_(void)192 dft_isgga_(void)
193 { return selected_func->is_gga(); }
194
195 int
dft_isgga__(void)196 dft_isgga__(void)
197 { return selected_func->is_gga(); }
198