Skip to content

Commit 5e9b513

Browse files
author
Roberto Di Remigio
committed
Add free function in interface to initialize Molecule
1 parent 56a0c1b commit 5e9b513

File tree

6 files changed

+96
-17
lines changed

6 files changed

+96
-17
lines changed

src/interface/Interface.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,54 @@ void initAtoms(Eigen::VectorXd & charges_, Eigen::Matrix3Xd & sphereCenter_)
625625
collect_atoms(chg, centers);
626626
}
627627

628+
void initMolecule(Molecule & molecule_)
629+
{
630+
// Gather information necessary to build molecule_
631+
// 1. number of atomic centers
632+
int nuclei;
633+
collect_nctot(&nuclei);
634+
// 2. position and charges of atomic centers
635+
Eigen::Matrix3Xd centers = Eigen::Matrix3Xd::Zero(Eigen::NoChange, nuclei);
636+
Eigen::VectorXd charges = Eigen::VectorXd::Zero(nuclei);
637+
double * chg = charges.data();
638+
double * pos = centers.data();
639+
collect_atoms(chg, pos);
640+
// 3. list of atoms and list of spheres
641+
bool scaling = parsedInput->scaling();
642+
std::string set = parsedInput->radiiSet();
643+
double factor = angstromToBohr(parsedInput->CODATAyear());
644+
std::vector<Atom> radiiSet, atoms;
645+
if ( set == "UFF" ) {
646+
radiiSet = Atom::initUFF();
647+
} else {
648+
radiiSet = Atom::initBondi();
649+
}
650+
std::vector<Sphere> spheres;
651+
for (int i = 0; i < charges.size(); ++i) {
652+
int index = int(charges(i)) - 1;
653+
atoms.push_back(radiiSet[index]);
654+
double radius = radiiSet[index].atomRadius() * factor;
655+
if (scaling) {
656+
radius *= radiiSet[index].atomRadiusScaling();
657+
}
658+
spheres.push_back(Sphere(centers.col(i), radius));
659+
}
660+
// 4. masses
661+
Eigen::VectorXd masses = Eigen::VectorXd::Zero(nuclei);
662+
for (int i = 0; i < masses.size(); ++i) {
663+
masses(i) = atoms[i].atomMass();
664+
}
665+
// Based on the creation mode (Implicit or Atoms)
666+
// the spheres list might need postprocessing
667+
std::string _mode = parsedInput->mode();
668+
if ( _mode == "ATOMS" ) {
669+
initSpheresAtoms(centers, spheres);
670+
}
671+
672+
// OK, now get molecule_
673+
molecule_ = Molecule(nuclei, charges, masses, centers, atoms, spheres);
674+
}
675+
628676
void initSpheresAtoms(const Eigen::Matrix3Xd & sphereCenter_,
629677
std::vector<Sphere> & spheres_)
630678
{

src/interface/Interface.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <Eigen/Dense>
4141

4242
#include "InputManager.hpp"
43+
#include "Molecule.hpp"
4344
#include "Sphere.hpp"
4445

4546
/*
@@ -311,6 +312,13 @@ void initWaveletCavity();
311312
*/
312313
void initAtoms(Eigen::VectorXd & charges_, Eigen::Matrix3Xd & sphereCenter_);
313314

315+
/*! \fn void initMolecule(Molecule & molecule_, Eigen::Matrix3Xd & sphereCenter_)
316+
* \param[out] molecule_ a Molecule object
317+
*
318+
* Initializes Molecule object with all the information on charges, masses and positions of atomic centers
319+
*/
320+
void initMolecule(Molecule & molecule_);
321+
314322
/*! \fn void initSpheresImplicit(const Eigen::VectorXd & charges_, const Eigen::Matrix3Xd & sphereCenter_, std::vector<Sphere> & spheres_)
315323
* \param[in] charges_ contains charges of atomic centers
316324
* \param[in] sphereCenter_ contains coordinates of atomic centers

src/utils/Input.cpp.in

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,14 +265,15 @@ void Input::reader(const char * pythonParsed)
265265
if (mode_ == "EXPLICIT") {
266266
std::vector<double> spheresInput = cavity.getDblVec("SPHERES");
267267
int j = 0;
268-
int upperBound = int(spheresInput.size() / 4);
269-
for (int i = 0; i < upperBound; ++i) {
268+
int nAtoms = int(spheresInput.size() / 4);
269+
for (int i = 0; i < nAtoms; ++i) {
270270
Eigen::Vector3d center;
271271
center << spheresInput[j], spheresInput[j+1], spheresInput[j+2];
272272
Sphere sph(center, spheresInput[j+3]);
273273
spheres_.push_back(sph);
274274
j += 4;
275275
}
276+
molecule_ = Molecule(nAtoms, spheres_);
276277
} else if (mode_ == "ATOMS") {
277278
atoms_ = cavity.getIntVec("ATOMS");
278279
radii_ = cavity.getDblVec("RADII");

src/utils/Input.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "Getkw.h"
3535

3636
#include "InputManager.hpp"
37+
#include "Molecule.hpp"
3738
#include "Solvent.hpp"
3839
#include "Sphere.hpp"
3940

@@ -93,6 +94,8 @@ class Input
9394
std::vector<Sphere> spheres() { return spheres_; }
9495
Sphere spheres(int i) { return spheres_[i]; }
9596
void spheres(const std::vector<Sphere> & sph) { spheres_ = sph; }
97+
Molecule molecule() { return molecule_; }
98+
void molecule(const Molecule & m) { molecule_ = m; }
9699
// Medium section input
97100
Solvent solvent() { return solvent_; }
98101
bool fromSolvent() { return hasSolvent_; }
@@ -174,6 +177,8 @@ class Input
174177
std::vector<double> radii_;
175178
/// List of spheres for fully custom cavity generation
176179
std::vector<Sphere> spheres_;
180+
/// Molecule or atomic aggregate
181+
Molecule molecule_;
177182
/// The solvent for a vacuum/uniform dielectric run
178183
Solvent solvent_;
179184
/// Whether the medium was initialized from a solvent object

src/utils/Molecule.cpp

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,29 @@
3939
#include "MathUtils.hpp"
4040

4141
Molecule::Molecule(int nat, const Eigen::VectorXd & chg, const Eigen::VectorXd & m,
42-
const Eigen::MatrixX3d & geo, const std::vector<Atom> & at, const std::vector<Sphere> & sph)
42+
const Eigen::Matrix3Xd & geo, const std::vector<Atom> & at, const std::vector<Sphere> & sph)
4343
: nAtoms_(nat), charges_(chg), masses_(m), geometry_(geo), atoms_(at), spheres_(sph)
4444
{
4545
rotor_ = findRotorType();
4646
}
4747

48+
Molecule::Molecule(int nat, const std::vector<Sphere> & sph)
49+
: nAtoms_(nat), spheres_(sph)
50+
{
51+
// This constructor is used when initializing the Molecule in EXPLICIT mode
52+
// charges are set to 1.0; masses are set based on the radii; geometry is set from the list of spheres
53+
charges_ = Eigen::VectorXd::Ones(nAtoms_);
54+
for (int i = 0; i < nAtoms_; ++i) {
55+
masses_(i) = spheres_[i].radius();
56+
geometry_.col(i) = spheres_[i].center();
57+
double charge = charges_(i);
58+
double mass = masses_(i);
59+
// All the atoms are dummies
60+
atoms_[i] = Atom("Dummy", "Du", charge, mass, mass, geometry_.col(i));
61+
}
62+
rotor_ = findRotorType();
63+
}
64+
4865

4966
Molecule::Molecule(const Molecule &other){
5067
*this = other;
@@ -65,14 +82,14 @@ Eigen::Matrix3d Molecule::inertiaTensor(){
6582

6683
for (int i = 0; i < nAtoms_; ++i){
6784
// Diagonal
68-
inertia(0,0) += masses_(i) * (geometry_(i,1) * geometry_(i,1) + geometry_(i,2) * geometry_(i,2));
69-
inertia(1,1) += masses_(i) * (geometry_(i,0) * geometry_(i,0) + geometry_(i,2) * geometry_(i,2));
70-
inertia(2,2) += masses_(i) * (geometry_(i,0) * geometry_(i,0) + geometry_(i,1) * geometry_(i,1));
85+
inertia(0,0) += masses_(i) * (geometry_(1,i) * geometry_(1,i) + geometry_(2,i) * geometry_(2,i));
86+
inertia(1,1) += masses_(i) * (geometry_(0,i) * geometry_(0,i) + geometry_(2,i) * geometry_(2,i));
87+
inertia(2,2) += masses_(i) * (geometry_(0,i) * geometry_(0,i) + geometry_(1,i) * geometry_(1,i));
7188

7289
// Off-diagonal
73-
inertia(0,1) -= masses_(i) * (geometry_(i,0) * geometry_(i,1));
74-
inertia(0,2) -= masses_(i) * (geometry_(i,0) * geometry_(i,2));
75-
inertia(1,2) -= masses_(i) * (geometry_(i,1) * geometry_(i,2));
90+
inertia(0,1) -= masses_(i) * (geometry_(0,i) * geometry_(1,i));
91+
inertia(0,2) -= masses_(i) * (geometry_(0,i) * geometry_(2,i));
92+
inertia(1,2) -= masses_(i) * (geometry_(1,i) * geometry_(2,i));
7693
}
7794
// Now symmetrize
7895
hermitivitize(inertia);
@@ -134,8 +151,8 @@ rotorType Molecule::findRotorType(){
134151
void Molecule::translate(const Eigen::Vector3d &translationVector){
135152
// Translate the geometry_ matrix and update the geometric data in atoms_.
136153
for (int i = 0; i < nAtoms_; ++i){
137-
geometry_.row(i) -= translationVector;
138-
Eigen::Vector3d tmp = geometry_.row(i).transpose();
154+
geometry_.col(i) -= translationVector;
155+
Eigen::Vector3d tmp = geometry_.col(i);
139156
atoms_[i].atomCoord(tmp);
140157
}
141158
}
@@ -149,7 +166,7 @@ void Molecule::rotate(const Eigen::Matrix3d &rotationMatrix){
149166
// Rotate the geometry_ matrix and update the geometric data in atoms_.
150167
geometry_ *= rotationMatrix; // The power of Eigen: geometry_ = geometry_ * rotationMatrix;
151168
for (int i = 0; i < nAtoms_; ++i){
152-
Eigen::Vector3d tmp = geometry_.row(i).transpose();
169+
Eigen::Vector3d tmp = geometry_.col(i);
153170
atoms_[i].atomCoord(tmp);
154171
}
155172
}
@@ -190,7 +207,7 @@ std::ostream & operator<<(std::ostream &os, const Molecule &m){
190207
os << " Center X Y Z " << std::endl;
191208
os << " ------------ ----------------- ----------------- -----------------" << std::endl;
192209
for (int i = 0; i < m.nAtoms_; ++i){
193-
os << std::setw(10) << m.atoms_[i].atomSymbol() << std::setw(15) <<m.geometry_.row(i).format(CleanFmt) << std::endl;
210+
os << std::setw(10) << m.atoms_[i].atomSymbol() << std::setw(15) <<m.geometry_.col(i).transpose().format(CleanFmt) << std::endl;
194211
}
195212
} else {
196213
os << " No atoms in this molecule!" << std::endl;

src/utils/Molecule.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class Molecule {
6060
Eigen::VectorXd masses_;
6161
/// Molecular geometry, in cartesian coordinates. The dimensions are (# atoms * 3)
6262
/// Units are Bohr.
63-
Eigen::MatrixX3d geometry_;
63+
Eigen::Matrix3Xd geometry_;
6464
/// A container for all the atoms composing the molecule
6565
std::vector<Atom> atoms_;
6666
/// A container for the spheres composing the molecule
@@ -69,17 +69,17 @@ class Molecule {
6969
rotorType rotor_;
7070
public:
7171
Molecule() {}
72-
/// Constructor
7372
Molecule(int nat, const Eigen::VectorXd & chg, const Eigen::VectorXd & masses,
74-
const Eigen::MatrixX3d & geo, const std::vector<Atom> & at, const std::vector<Sphere> & sph);
73+
const Eigen::Matrix3Xd & geo, const std::vector<Atom> & at, const std::vector<Sphere> & sph);
74+
Molecule(int nat, const std::vector<Sphere> & sph);
7575
/// Copy constructor.
7676
Molecule(const Molecule &other);
7777
~Molecule(){}
7878

7979
int nAtoms() { return nAtoms_; }
8080
Eigen::VectorXd charges() { return charges_; }
8181
Eigen::VectorXd masses() { return masses_; }
82-
Eigen::MatrixX3d geometry() { return geometry_; }
82+
Eigen::Matrix3Xd geometry() { return geometry_; }
8383
std::vector<Atom> atoms() { return atoms_; }
8484
std::vector<Sphere> spheres() { return spheres_; }
8585

0 commit comments

Comments
 (0)