1 /*-
2  * Copyright (c) 2012-2017 Ilya Kaliman
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #ifndef LIBEFP_PRIVATE_H
28 #define LIBEFP_PRIVATE_H
29 
30 #include <assert.h>
31 
32 #include "efp.h"
33 #include "int.h"
34 #include "log.h"
35 #include "swf.h"
36 #include "terms.h"
37 #include "util.h"
38 
39 #define EFP_EXPORT
40 
41 #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
42 
43 struct multipole_pt {
44 	double x, y, z;
45 	double monopole;
46 	vec_t dipole;
47 	double quadrupole[6];
48 	double octupole[10];
49 };
50 
51 struct polarizable_pt {
52 	double x, y, z;
53 	mat_t tensor;
54 	vec_t elec_field;
55 	vec_t elec_field_wf;
56 };
57 
58 struct dynamic_polarizable_pt {
59 	double x, y, z;
60 	mat_t tensor[12];
61 };
62 
63 struct ff_atom {
64 	char type[32]; /* atom type in force field */
65 	size_t idx;    /* index in atoms array */
66 };
67 
68 struct ff_link {
69 	size_t idx1;   /* index in ff_atoms array */
70 	size_t idx2;   /* index in ff_atoms array */
71 };
72 
73 struct frag {
74 	/* fragment name */
75 	char name[32];
76 
77 	/* fragment center of mass */
78 	double x, y, z;
79 
80 	/* rotation matrix representing orientation of a fragment */
81 	mat_t rotmat;
82 
83 	/* pointer to the initial fragment state in library */
84 	const struct frag *lib;
85 
86 	/* number of atoms in this fragment */
87 	size_t n_atoms;
88 
89 	/* fragment atoms */
90 	struct efp_atom *atoms;
91 
92 	/* distributed multipoles */
93 	struct multipole_pt *multipole_pts;
94 
95 	/* number of distributed multipole points */
96 	size_t n_multipole_pts;
97 
98 	/* electrostatic screening parameters */
99 	double *screen_params;
100 
101 	/* ab initio electrostatic screening parameters */
102 	double *ai_screen_params;
103 
104 	/* polarization damping parameter */
105 	double pol_damp;
106 
107 	/* distributed polarizability points */
108 	struct polarizable_pt *polarizable_pts;
109 
110 	/* number of distributed polarizability points */
111 	size_t n_polarizable_pts;
112 
113 	/* dynamic polarizability points */
114 	struct dynamic_polarizable_pt *dynamic_polarizable_pts;
115 
116 	/* number of dynamic polarizability points */
117 	size_t n_dynamic_polarizable_pts;
118 
119 	/* number of localized molecular orbitals */
120 	size_t n_lmo;
121 
122 	/* localized molecular orbital centroids */
123 	vec_t *lmo_centroids;
124 
125 	/* spin multiplicity */
126 	int multiplicity;
127 
128 	/* number of exchange repulsion atoms */
129 	size_t n_xr_atoms;
130 
131 	/* exchange repulsion atoms */
132 	struct xr_atom *xr_atoms;
133 
134 	/* upper triangle of fock matrix, size = n_lmo * (n_lmo + 1) / 2 */
135 	double *xr_fock_mat;
136 
137 	/* exchange repulsion wavefunction size */
138 	size_t xr_wf_size;
139 
140 	/* exchange repulsion wavefunction, size = n_lmo * xr_wf_size */
141 	double *xr_wf;
142 
143 	/* rotational derivatives of MO coefficients */
144 	double *xr_wf_deriv[3];
145 
146 	/* fitted ai-efp exchange-repulsion parameters */
147 	double *xrfit;
148 
149 	/* offset of polarizable points for this fragment */
150 	size_t polarizable_offset;
151 };
152 
153 struct efp {
154 	/* number of fragments */
155 	size_t n_frag;
156 
157 	/* array of fragments */
158 	struct frag *frags;
159 
160 	/* number of fragments in the library */
161 	size_t n_lib;
162 
163 	/* array with the library of fragment initial parameters */
164 	struct frag **lib;
165 
166 	/* callback which computes electric field from electrons */
167 	efp_electron_density_field_fn get_electron_density_field;
168 
169 	/* user data for get_electron_density_field */
170 	void *get_electron_density_field_user_data;
171 
172 	/* user parameters for this EFP computation */
173 	struct efp_opts opts;
174 
175 	/* gradient will also be computed if nonzero */
176 	int do_gradient;
177 
178 	/* periodic simulation box size */
179 	vec_t box;
180 
181 	/* stress tensor */
182 	mat_t stress;
183 
184 	/* force and torque on fragments */
185 	six_t *grad;
186 
187 	/* number of point charges */
188 	size_t n_ptc;
189 
190 	/* coordinates of point charges */
191 	vec_t *ptc_xyz;
192 
193 	/* point charges */
194 	double *ptc;
195 
196 	/* gradient on point charges */
197 	vec_t *ptc_grad;
198 
199 	/* polarization induced dipoles */
200 	vec_t *indip;
201 
202 	/* polarization conjugate induced dipoles */
203 	vec_t *indipconj;
204 
205 	/* total number of polarizable points */
206 	size_t n_polarizable_pts;
207 
208 	/* number of core orbitals in ab initio subsystem */
209 	size_t n_ai_core;
210 
211 	/* number of active orbitals in ab initio subsystem */
212 	size_t n_ai_act;
213 
214 	/* number of virtual orbitals in ab initio subsystem */
215 	size_t n_ai_vir;
216 
217 	/* ab initio orbital energies
218 	 * size [n_ai_occ + n_ai_vir] */
219 	double *ai_orbital_energies;
220 
221 	/* ab initio dipole moment integrals on polarizable points
222 	 * size [3 * (n_ai_occ + n_ai_vir) ^ 2] */
223 	double *ai_dipole_integrals;
224 
225 	/* EFP energy terms */
226 	struct efp_energy energy;
227 
228 	/* skip-list of fragments - boolean array of nfrag^2 elements */
229 	char *skiplist;
230 };
231 
232 #endif /* LIBEFP_PRIVATE_H */
233