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