48#include "optimization/PotentialEnergyObjectiveFunction.hpp"
56 PotentialEnergyObjectiveFunction::PotentialEnergyObjectiveFunction(
59 forceMan_(forceMan), thermo(info), hasFlucQ_(false) {
60 shake_ =
new Shake(info_);
62 if (info_->usesFluctuatingCharges()) {
63 if (info_->getNFluctuatingCharges() > 0) {
66 bool cr = info_->getSimParams()
67 ->getFluctuatingChargeParameters()
68 ->getConstrainRegions();
69 fqConstraints_->setConstrainRegions(cr);
74 PotentialEnergyObjectiveFunction::~PotentialEnergyObjectiveFunction() {
81 shake_->constraintR();
82 forceMan_->calcForces();
83 if (hasFlucQ_) fqConstraints_->applyConstraints();
84 shake_->constraintF();
85 return thermo.getPotential();
91 shake_->constraintR();
92 forceMan_->calcForces();
93 if (hasFlucQ_) fqConstraints_->applyConstraints();
94 shake_->constraintF();
101 shake_->constraintR();
102 forceMan_->calcForces();
103 if (hasFlucQ_) fqConstraints_->applyConstraints();
104 shake_->constraintF();
106 return thermo.getPotential();
109 void PotentialEnergyObjectiveFunction::setCoor(
113 SimInfo::MoleculeIterator i;
114 Molecule::IntegrableObjectIterator j;
115 Molecule::AtomIterator ai;
124 index = displacements_[myrank_];
133 for (sd = mol->beginIntegrableObject(j); sd != NULL;
134 sd = mol->nextIntegrableObject(j)) {
135 position[0] = x[index++];
136 position[1] = x[index++];
137 position[2] = x[index++];
142 eulerAngle[0] = x[index++];
143 eulerAngle[1] = x[index++];
144 eulerAngle[2] = x[index++];
157 for (mol = info_->beginMolecule(i); mol != NULL;
158 mol = info_->nextMolecule(i)) {
159 for (atom = mol->beginFluctuatingCharge(ai); atom != NULL;
160 atom = mol->nextFluctuatingCharge(ai)) {
167 void PotentialEnergyObjectiveFunction::getGrad(
169 SimInfo::MoleculeIterator i;
170 Molecule::IntegrableObjectIterator j;
171 Molecule::AtomIterator ai;
175 std::vector<RealType> myGrad;
179 index = displacements_[myrank_];
185 for (mol = info_->beginMolecule(i); mol != NULL;
186 mol = info_->nextMolecule(i)) {
187 for (sd = mol->beginIntegrableObject(j); sd != NULL;
188 sd = mol->nextIntegrableObject(j)) {
191 for (
size_t k = 0; k < myGrad.size(); ++k) {
192 grad[index++] = myGrad[k];
198 for (mol = info_->beginMolecule(i); mol != NULL;
199 mol = info_->nextMolecule(i)) {
200 for (atom = mol->beginFluctuatingCharge(ai); atom != NULL;
201 atom = mol->nextFluctuatingCharge(ai)) {
207 MPI_Allreduce(MPI_IN_PLACE, &grad[0], ndf_, MPI_REALTYPE, MPI_SUM,
214 MPI_Comm_size(MPI_COMM_WORLD, &nproc_);
215 MPI_Comm_rank(MPI_COMM_WORLD, &myrank_);
216 std::vector<int> onProc(nproc_, 0);
218 displacements_.clear();
219 displacements_.resize(nproc_, 0);
222 SimInfo::MoleculeIterator i;
223 Molecule::IntegrableObjectIterator j;
224 Molecule::AtomIterator ai;
234 for (mol = info_->beginMolecule(i); mol != NULL;
235 mol = info_->nextMolecule(i)) {
236 for (sd = mol->beginIntegrableObject(j); sd != NULL;
237 sd = mol->nextIntegrableObject(j)) {
245 for (mol = info_->beginMolecule(i); mol != NULL;
246 mol = info_->nextMolecule(i)) {
247 for (atom = mol->beginFluctuatingCharge(ai); atom != NULL;
248 atom = mol->nextFluctuatingCharge(ai)) {
255 MPI_Allgather(&ndf_, 1, MPI_INT, &onProc[0], 1, MPI_INT, MPI_COMM_WORLD);
258 for (
int iproc = 0; iproc < nproc_; iproc++) {
259 ndf_ += onProc[iproc];
262 displacements_[0] = 0;
263 for (
int iproc = 1; iproc < nproc_; iproc++) {
264 displacements_[iproc] = displacements_[iproc - 1] + onProc[iproc - 1];
268 DynamicVector<RealType> xinit(ndf_, 0.0);
272 index = displacements_[myrank_];
277 for (mol = info_->beginMolecule(i); mol != NULL;
278 mol = info_->nextMolecule(i)) {
279 for (sd = mol->beginIntegrableObject(j); sd != NULL;
280 sd = mol->nextIntegrableObject(j)) {
282 xinit[index++] = pos[0];
283 xinit[index++] = pos[1];
284 xinit[index++] = pos[2];
288 xinit[index++] = eulerAngle[0];
289 xinit[index++] = eulerAngle[1];
290 xinit[index++] = eulerAngle[2];
296 for (mol = info_->beginMolecule(i); mol != NULL;
297 mol = info_->nextMolecule(i)) {
298 for (atom = mol->beginFluctuatingCharge(ai); atom != NULL;
299 atom = mol->nextFluctuatingCharge(ai)) {
Dynamically-sized vector class.
void setZero()
zero out the vector
ForceManager is responsible for calculating both the short range (bonded) interactions and long range...
RealType value(const DynamicVector< RealType > &x)
method to overload to compute the objective function value in x
void gradient(DynamicVector< RealType > &grad, const DynamicVector< RealType > &x)
method to overload to compute grad_f, the first derivative of
RealType valueAndGradient(DynamicVector< RealType > &grad, const DynamicVector< RealType > &x)
method to overload to compute grad_f, the first derivative
void updateAtoms()
update the positions of atoms belong to this rigidbody
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
Molecule * beginMolecule(MoleculeIterator &i)
Returns the first molecule in this SimInfo and intialize the iterator.
Molecule * nextMolecule(MoleculeIterator &i)
Returns the next avaliable Molecule based on the iterator.
SnapshotManager * getSnapshotManager()
Returns the snapshot manager.
"Don't move, or you're dead! Stand up! Captain, we've got them!"
Vector3d getEuler()
Returns the current euler angles of this stuntDouble.
void setFlucQPos(RealType charge)
Sets the current fluctuating charge of this stuntDouble.
Vector3d getPos()
Returns the current position of this stuntDouble.
RealType getFlucQFrc()
Returns the current charge force of this stuntDouble.
RealType getFlucQPos()
Returns the current fluctuating charge of this stuntDouble.
void setPos(const Vector3d &pos)
Sets the current position of this stuntDouble.
void setEuler(const Vector3d &euler)
Sets the current euler angles of this stuntDouble.
bool isRigidBody()
Tests if this stuntDouble is a rigid body.
bool isDirectional()
Tests if this stuntDouble is a directional one.
virtual std::vector< RealType > getGrad()=0
Returns the gradient of this stuntDouble.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.