@@ -145,18 +145,25 @@ void Meddle::CTORBody() {
145145 << std::endl;
146146 infoStream_ << " Input parsing done " << input_.providedBy () << std::endl;
147147
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+ }
160167 }
161168}
162169
@@ -167,7 +174,8 @@ Meddle::Meddle(const Input & input, const HostWriter & write)
167174 cavity_(nullptr ),
168175 K_0_(nullptr ),
169176 K_d_(nullptr ),
170- hasDynamic_(false ) {
177+ hasDynamic_(false ),
178+ hasFQ_(false ) {
171179 input_.initMolecule ();
172180 CTORBody ();
173181}
@@ -179,7 +187,8 @@ Meddle::Meddle(const std::string & inputFileName, const HostWriter & write)
179187 cavity_(nullptr ),
180188 K_0_(nullptr ),
181189 K_d_(nullptr ),
182- hasDynamic_(false ) {
190+ hasDynamic_(false ),
191+ hasFQ_(false ) {
183192 input_.initMolecule ();
184193 CTORBody ();
185194}
@@ -196,7 +205,8 @@ Meddle::Meddle(int nr_nuclei,
196205 cavity_(nullptr ),
197206 K_0_(nullptr ),
198207 K_d_(nullptr ),
199- hasDynamic_(false ) {
208+ hasDynamic_(false ),
209+ hasFQ_(false ) {
200210 TIMER_ON (" Meddle::initInput" );
201211 initInput (nr_nuclei, charges, coordinates, symmetry_info);
202212 TIMER_OFF (" Meddle::initInput" );
@@ -216,7 +226,8 @@ Meddle::Meddle(int nr_nuclei,
216226 cavity_(nullptr ),
217227 K_0_(nullptr ),
218228 K_d_(nullptr ),
219- hasDynamic_(false ) {
229+ hasDynamic_(false ),
230+ hasFQ_(false ) {
220231 TIMER_ON (" Meddle::initInput" );
221232 initInput (nr_nuclei, charges, coordinates, symmetry_info);
222233 TIMER_OFF (" Meddle::initInput" );
@@ -235,7 +246,8 @@ Meddle::Meddle(int nr_nuclei,
235246 cavity_(nullptr ),
236247 K_0_(nullptr ),
237248 K_d_(nullptr ),
238- hasDynamic_(false ) {
249+ hasDynamic_(false ),
250+ hasFQ_(false ) {
239251 // This one does a deferred initialization:
240252 // The CTORBody function is not called at this point, but during refresh
241253 TIMER_ON (" Meddle::initInput" );
@@ -250,22 +262,26 @@ void pcmsolver_delete(pcmsolver_context_t * context) {
250262 delete AS_TYPE (pcm::Meddle, context);
251263}
252264pcm::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+ }
257273}
258274
259275PCMSolverIndex pcmsolver_get_cavity_size (pcmsolver_context_t * context) {
260276 return (AS_CTYPE (pcm::Meddle, context)->getCavitySize ());
261277}
262- PCMSolverIndex pcm::Meddle::getCavitySize () const { return cavity_-> size ( ); }
278+ PCMSolverIndex pcm::Meddle::getCavitySize () const { return std::get< 0 >(size_ ); }
263279
264280PCMSolverIndex pcmsolver_get_irreducible_cavity_size (pcmsolver_context_t * context) {
265281 return (AS_CTYPE (pcm::Meddle, context)->getIrreducibleCavitySize ());
266282}
267283PCMSolverIndex pcm::Meddle::getIrreducibleCavitySize () const {
268- return cavity_-> irreducible_size ( );
284+ return std::get< 1 >(size_ );
269285}
270286
271287void pcmsolver_get_centers (pcmsolver_context_t * context, double centers[]) {
@@ -275,16 +291,26 @@ void pcmsolver_get_centers(pcmsolver_context_t * context, double centers[]) {
275291}
276292void pcm::Meddle::getCenters (double centers[]) const {
277293 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+ }
280301 TIMER_OFF (" Meddle::getCenters" );
281302}
282303
283304void pcmsolver_get_center (pcmsolver_context_t * context, int its, double center[]) {
284305 AS_CTYPE (pcm::Meddle, context)->getCenter (its, center);
285306}
286307void 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+ }
288314}
289315
290316void pcmsolver_get_areas (pcmsolver_context_t * context, double areas[]) {
@@ -303,7 +329,16 @@ double pcmsolver_compute_polarization_energy(pcmsolver_context_t * context,
303329}
304330double pcm::Meddle::computePolarizationEnergy (const std::string & mep_name,
305331 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+ }
307342 return (energy / 2.0 );
308343}
309344
@@ -335,9 +370,14 @@ void pcm::Meddle::computeASC(const std::string & mep_name,
335370 int irrep) {
336371 // Get the proper iterators
337372 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+ }
341381 // Insert it into the map
342382 if (functions_.count (asc_name) == 1 ) { // Key in map already
343383 functions_[asc_name] = asc;
@@ -360,14 +400,18 @@ void pcm::Meddle::computeResponseASC(const std::string & mep_name,
360400 int irrep) {
361401 // Get the proper iterators
362402 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 ());
368414 }
369- // Renormalize
370- asc /= double (cavity_->pointGroup ().nrIrrep ());
371415 if (functions_.count (asc_name) == 1 ) { // Key in map already
372416 functions_[asc_name] = asc;
373417 } else { // Create key-value pair
@@ -387,7 +431,7 @@ void pcmsolver_get_surface_function(pcmsolver_context_t * context,
387431void pcm::Meddle::getSurfaceFunction (PCMSolverIndex size,
388432 double values[],
389433 const std::string & name) const {
390- if (cavity_-> size ( ) != size)
434+ if (std::get< 0 >(size_ ) != size)
391435 PCMSOLVER_ERROR (" The " + name + " SurfaceFunction is bigger than the cavity!" );
392436
393437 SurfaceFunctionMapConstIter iter = functions_.find (name);
@@ -408,7 +452,7 @@ void pcmsolver_set_surface_function(pcmsolver_context_t * context,
408452void pcm::Meddle::setSurfaceFunction (PCMSolverIndex size,
409453 double values[],
410454 const std::string & name) {
411- if (cavity_-> size ( ) != size)
455+ if (std::get< 0 >(size_ ) != size)
412456 PCMSOLVER_ERROR (" The " + name + " SurfaceFunction is bigger than the cavity!" );
413457
414458 Eigen::VectorXd func = Eigen::Map<Eigen::VectorXd>(values, size, 1 );
@@ -460,7 +504,7 @@ void pcmsolver_load_surface_function(pcmsolver_context_t * context,
460504void pcm::Meddle::loadSurfaceFunction (const std::string & name) {
461505 hostWriter_ (" \n Loading surface function " + name + " from .npy file" );
462506 Eigen::VectorXd values = cnpy::custom::npy_load<double >(name + " .npy" );
463- if (values.size () != cavity_-> size ( ))
507+ if (values.size () != std::get< 0 >(size_ ))
464508 PCMSOLVER_ERROR (" The loaded " + name +
465509 " surface function is bigger than the cavity!" );
466510 // Append to global map
@@ -656,6 +700,7 @@ void Meddle::initInput(int nr_nuclei,
656700void Meddle::initCavity () {
657701 cavity_ = cavity::bootstrapFactory ().create (input_.cavityParams ().cavityType ,
658702 input_.cavityParams ());
703+ size_ = std::make_tuple (cavity_->size (), cavity_->irreducible_size ());
659704 cavity_->saveCavity ();
660705
661706 infoStream_ << " ========== Cavity " << std::endl;
@@ -679,7 +724,7 @@ void Meddle::initStaticSolver() {
679724 delete biop;
680725
681726 // Perform Gauss' theorem check for nuclear charges
682- GaussCheck ();
727+ if (!hasFQ_) GaussCheck ();
683728
684729 infoStream_ << " ========== Static solver " << std::endl;
685730 infoStream_ << *K_0_ << std::endl;
0 commit comments