@@ -145,18 +145,25 @@ void Meddle::CTORBody() {
145
145
<< std::endl;
146
146
infoStream_ << " Input parsing done " << input_.providedBy () << std::endl;
147
147
148
- TIMER_ON (" Meddle::initCavity" );
149
- initCavity ();
150
- TIMER_OFF (" Meddle::initCavity" );
151
-
152
- TIMER_ON (" Meddle::initStaticSolver" );
153
- initStaticSolver ();
154
- TIMER_OFF (" Meddle::initStaticSolver" );
155
-
156
- if (input_.isDynamic ()) {
157
- TIMER_ON (" Meddle::initDynamicSolver" );
158
- initDynamicSolver ();
159
- TIMER_OFF (" Meddle::initDynamicSolver" );
148
+ if (input_.isFQ ()) { /* MMFQ calculation */
149
+ hasFQ_ = true ;
150
+ TIMER_ON (" Meddle::initMMFQ" );
151
+ initMMFQ ();
152
+ TIMER_OFF (" Meddle::initMMFQ" );
153
+ } else { /* Pure PCM calculation */
154
+ TIMER_ON (" Meddle::initCavity" );
155
+ initCavity ();
156
+ TIMER_OFF (" Meddle::initCavity" );
157
+
158
+ TIMER_ON (" Meddle::initStaticSolver" );
159
+ initStaticSolver ();
160
+ TIMER_OFF (" Meddle::initStaticSolver" );
161
+
162
+ if (input_.isDynamic ()) {
163
+ TIMER_ON (" Meddle::initDynamicSolver" );
164
+ initDynamicSolver ();
165
+ TIMER_OFF (" Meddle::initDynamicSolver" );
166
+ }
160
167
}
161
168
}
162
169
@@ -167,7 +174,8 @@ Meddle::Meddle(const Input & input, const HostWriter & write)
167
174
cavity_(nullptr ),
168
175
K_0_(nullptr ),
169
176
K_d_(nullptr ),
170
- hasDynamic_(false ) {
177
+ hasDynamic_(false ),
178
+ hasFQ_(false ) {
171
179
input_.initMolecule ();
172
180
CTORBody ();
173
181
}
@@ -179,7 +187,8 @@ Meddle::Meddle(const std::string & inputFileName, const HostWriter & write)
179
187
cavity_(nullptr ),
180
188
K_0_(nullptr ),
181
189
K_d_(nullptr ),
182
- hasDynamic_(false ) {
190
+ hasDynamic_(false ),
191
+ hasFQ_(false ) {
183
192
input_.initMolecule ();
184
193
CTORBody ();
185
194
}
@@ -196,7 +205,8 @@ Meddle::Meddle(int nr_nuclei,
196
205
cavity_(nullptr ),
197
206
K_0_(nullptr ),
198
207
K_d_(nullptr ),
199
- hasDynamic_(false ) {
208
+ hasDynamic_(false ),
209
+ hasFQ_(false ) {
200
210
TIMER_ON (" Meddle::initInput" );
201
211
initInput (nr_nuclei, charges, coordinates, symmetry_info);
202
212
TIMER_OFF (" Meddle::initInput" );
@@ -216,7 +226,8 @@ Meddle::Meddle(int nr_nuclei,
216
226
cavity_(nullptr ),
217
227
K_0_(nullptr ),
218
228
K_d_(nullptr ),
219
- hasDynamic_(false ) {
229
+ hasDynamic_(false ),
230
+ hasFQ_(false ) {
220
231
TIMER_ON (" Meddle::initInput" );
221
232
initInput (nr_nuclei, charges, coordinates, symmetry_info);
222
233
TIMER_OFF (" Meddle::initInput" );
@@ -235,7 +246,8 @@ Meddle::Meddle(int nr_nuclei,
235
246
cavity_(nullptr ),
236
247
K_0_(nullptr ),
237
248
K_d_(nullptr ),
238
- hasDynamic_(false ) {
249
+ hasDynamic_(false ),
250
+ hasFQ_(false ) {
239
251
// This one does a deferred initialization:
240
252
// The CTORBody function is not called at this point, but during refresh
241
253
TIMER_ON (" Meddle::initInput" );
@@ -250,22 +262,26 @@ void pcmsolver_delete(pcmsolver_context_t * context) {
250
262
delete AS_TYPE (pcm::Meddle, context);
251
263
}
252
264
pcm::Meddle::~Meddle () {
253
- delete cavity_;
254
- delete K_0_;
255
- if (hasDynamic_)
256
- delete K_d_;
265
+ if (hasFQ_) { /* MMFQ calculation */
266
+ delete FQ_;
267
+ } else { /* Pure PCM calculation */
268
+ delete cavity_;
269
+ delete K_0_;
270
+ if (hasDynamic_)
271
+ delete K_d_;
272
+ }
257
273
}
258
274
259
275
PCMSolverIndex pcmsolver_get_cavity_size (pcmsolver_context_t * context) {
260
276
return (AS_CTYPE (pcm::Meddle, context)->getCavitySize ());
261
277
}
262
- PCMSolverIndex pcm::Meddle::getCavitySize () const { return cavity_-> size ( ); }
278
+ PCMSolverIndex pcm::Meddle::getCavitySize () const { return std::get< 0 >(size_ ); }
263
279
264
280
PCMSolverIndex pcmsolver_get_irreducible_cavity_size (pcmsolver_context_t * context) {
265
281
return (AS_CTYPE (pcm::Meddle, context)->getIrreducibleCavitySize ());
266
282
}
267
283
PCMSolverIndex pcm::Meddle::getIrreducibleCavitySize () const {
268
- return cavity_-> irreducible_size ( );
284
+ return std::get< 1 >(size_ );
269
285
}
270
286
271
287
void pcmsolver_get_centers (pcmsolver_context_t * context, double centers[]) {
@@ -275,16 +291,26 @@ void pcmsolver_get_centers(pcmsolver_context_t * context, double centers[]) {
275
291
}
276
292
void pcm::Meddle::getCenters (double centers[]) const {
277
293
TIMER_ON (" Meddle::getCenters" );
278
- Eigen::Map<Eigen::Matrix3Xd>(centers, 3 , cavity_->size ()) =
279
- cavity_->elementCenter ();
294
+ if (hasFQ_) { /* MMFQ calculation */
295
+ PCMSolverIndex size = input_.fragments ().sites .cols ();
296
+ Eigen::Map<Eigen::Matrix3Xd>(centers, 3 , size) = input_.fragments ().sites ;
297
+ } else { /* Pure PCM calculation */
298
+ Eigen::Map<Eigen::Matrix3Xd>(centers, 3 , cavity_->size ()) =
299
+ cavity_->elementCenter ();
300
+ }
280
301
TIMER_OFF (" Meddle::getCenters" );
281
302
}
282
303
283
304
void pcmsolver_get_center (pcmsolver_context_t * context, int its, double center[]) {
284
305
AS_CTYPE (pcm::Meddle, context)->getCenter (its, center);
285
306
}
286
307
void pcm::Meddle::getCenter (int its, double center[]) const {
287
- Eigen::Map<Eigen::Vector3d>(center, 3 , 1 ) = cavity_->elementCenter (its - 1 );
308
+ if (hasFQ_) { /* MMFQ calculation */
309
+ Eigen::Map<Eigen::Matrix3Xd>(center, 3 , 1 ) =
310
+ input_.fragments ().sites .col (its - 1 );
311
+ } else { /* Pure PCM calculation */
312
+ Eigen::Map<Eigen::Vector3d>(center, 3 , 1 ) = cavity_->elementCenter (its - 1 );
313
+ }
288
314
}
289
315
290
316
void pcmsolver_get_areas (pcmsolver_context_t * context, double areas[]) {
@@ -303,7 +329,16 @@ double pcmsolver_compute_polarization_energy(pcmsolver_context_t * context,
303
329
}
304
330
double pcm::Meddle::computePolarizationEnergy (const std::string & mep_name,
305
331
const std::string & asc_name) const {
306
- double energy = functions_.at (mep_name).dot (functions_.at (asc_name));
332
+ double energy = 0.0 ;
333
+ if (hasFQ_) { /* MMFQ calculation */
334
+ // Dot product of MEP + Electronegativities times Fluctuating charges
335
+ energy = (functions_.at (mep_name) + input_.fragments ().chi )
336
+ .dot (functions_.at (asc_name));
337
+ } else { /* Pure PCM calculation */
338
+ // Dot product of MEP and ASC surface function
339
+ energy =
340
+ functions_.at (mep_name).dot (functions_.at (asc_name));
341
+ }
307
342
return (energy / 2.0 );
308
343
}
309
344
@@ -335,9 +370,14 @@ void pcm::Meddle::computeASC(const std::string & mep_name,
335
370
int irrep) {
336
371
// Get the proper iterators
337
372
SurfaceFunctionMapConstIter iter_pot = functions_.find (mep_name);
338
- Eigen::VectorXd asc = K_0_->computeCharge (iter_pot->second , irrep);
339
- // Renormalize
340
- asc /= double (cavity_->pointGroup ().nrIrrep ());
373
+ Eigen::VectorXd asc = Eigen::VectorXd::Zero (iter_pot->second .size ());
374
+ if (hasFQ_) { /* MMFQ calculation */
375
+ asc = FQ_->computeCharge (iter_pot->second );
376
+ } else { /* Pure PCM calculation */
377
+ asc = K_0_->computeCharge (iter_pot->second , irrep);
378
+ // Renormalize
379
+ asc /= double (cavity_->pointGroup ().nrIrrep ());
380
+ }
341
381
// Insert it into the map
342
382
if (functions_.count (asc_name) == 1 ) { // Key in map already
343
383
functions_[asc_name] = asc;
@@ -360,14 +400,18 @@ void pcm::Meddle::computeResponseASC(const std::string & mep_name,
360
400
int irrep) {
361
401
// Get the proper iterators
362
402
SurfaceFunctionMapConstIter iter_pot = functions_.find (mep_name);
363
- Eigen::VectorXd asc (cavity_->size ());
364
- if (hasDynamic_) {
365
- asc = K_d_->computeCharge (iter_pot->second , irrep);
366
- } else {
367
- asc = K_0_->computeCharge (iter_pot->second , irrep);
403
+ Eigen::VectorXd asc = Eigen::VectorXd::Zero (iter_pot->second .size ());
404
+ if (hasFQ_) { /* MMFQ calculation */
405
+ asc = FQ_->computeCharge (iter_pot->second );
406
+ } else { /* Pure PCM calculation */
407
+ if (hasDynamic_) {
408
+ asc = K_d_->computeCharge (iter_pot->second , irrep);
409
+ } else {
410
+ asc = K_0_->computeCharge (iter_pot->second , irrep);
411
+ }
412
+ // Renormalize
413
+ asc /= double (cavity_->pointGroup ().nrIrrep ());
368
414
}
369
- // Renormalize
370
- asc /= double (cavity_->pointGroup ().nrIrrep ());
371
415
if (functions_.count (asc_name) == 1 ) { // Key in map already
372
416
functions_[asc_name] = asc;
373
417
} else { // Create key-value pair
@@ -387,7 +431,7 @@ void pcmsolver_get_surface_function(pcmsolver_context_t * context,
387
431
void pcm::Meddle::getSurfaceFunction (PCMSolverIndex size,
388
432
double values[],
389
433
const std::string & name) const {
390
- if (cavity_-> size ( ) != size)
434
+ if (std::get< 0 >(size_ ) != size)
391
435
PCMSOLVER_ERROR (" The " + name + " SurfaceFunction is bigger than the cavity!" );
392
436
393
437
SurfaceFunctionMapConstIter iter = functions_.find (name);
@@ -408,7 +452,7 @@ void pcmsolver_set_surface_function(pcmsolver_context_t * context,
408
452
void pcm::Meddle::setSurfaceFunction (PCMSolverIndex size,
409
453
double values[],
410
454
const std::string & name) {
411
- if (cavity_-> size ( ) != size)
455
+ if (std::get< 0 >(size_ ) != size)
412
456
PCMSOLVER_ERROR (" The " + name + " SurfaceFunction is bigger than the cavity!" );
413
457
414
458
Eigen::VectorXd func = Eigen::Map<Eigen::VectorXd>(values, size, 1 );
@@ -460,7 +504,7 @@ void pcmsolver_load_surface_function(pcmsolver_context_t * context,
460
504
void pcm::Meddle::loadSurfaceFunction (const std::string & name) {
461
505
hostWriter_ (" \n Loading surface function " + name + " from .npy file" );
462
506
Eigen::VectorXd values = cnpy::custom::npy_load<double >(name + " .npy" );
463
- if (values.size () != cavity_-> size ( ))
507
+ if (values.size () != std::get< 0 >(size_ ))
464
508
PCMSOLVER_ERROR (" The loaded " + name +
465
509
" surface function is bigger than the cavity!" );
466
510
// Append to global map
@@ -656,6 +700,7 @@ void Meddle::initInput(int nr_nuclei,
656
700
void Meddle::initCavity () {
657
701
cavity_ = cavity::bootstrapFactory ().create (input_.cavityParams ().cavityType ,
658
702
input_.cavityParams ());
703
+ size_ = std::make_tuple (cavity_->size (), cavity_->irreducible_size ());
659
704
cavity_->saveCavity ();
660
705
661
706
infoStream_ << " ========== Cavity " << std::endl;
@@ -679,7 +724,7 @@ void Meddle::initStaticSolver() {
679
724
delete biop;
680
725
681
726
// Perform Gauss' theorem check for nuclear charges
682
- GaussCheck ();
727
+ if (!hasFQ_) GaussCheck ();
683
728
684
729
infoStream_ << " ========== Static solver " << std::endl;
685
730
infoStream_ << *K_0_ << std::endl;
0 commit comments