51#include "brains/Thermo.hpp"
52#include "integrators/IntegratorCreator.hpp"
54#include "utils/Constants.hpp"
55#include "utils/simError.h"
60 SimInfo::MoleculeIterator i;
61 Molecule::IntegrableObjectIterator j;
74 instaTemp = thermo.getTemperature();
75 press = thermo.getPressureTensor();
76 instaPress = Constants::pressureConvert *
77 (press(0, 0) + press(1, 1) + press(2, 2)) / 3.0;
78 instaVol = thermo.getVolume();
80 Vector3d COM = thermo.getCom();
86 for (mol = info_->beginMolecule(i); mol != NULL;
87 mol = info_->nextMolecule(i)) {
88 for (sd = mol->beginIntegrableObject(j); sd != NULL;
89 sd = mol->nextIntegrableObject(j)) {
95 getVelScaleA(sc, vel);
99 vel += dt2 * Constants::energyConvert / mass * frc - dt2 * sc;
102 if (sd->isDirectional()) {
105 Tb = sd->lab2Body(sd->getTrq());
111 ji += dt2 * Constants::energyConvert * Tb;
113 rotAlgo_->rotate(sd, ji, dt);
125 for (mol = info_->beginMolecule(i); mol != NULL;
126 mol = info_->nextMolecule(i)) {
127 for (sd = mol->beginIntegrableObject(j); sd != NULL;
128 sd = mol->nextIntegrableObject(j)) {
129 oldPos[index++] = sd->getPos();
135 for (
int k = 0; k < maxIterNum_; k++) {
137 for (mol = info_->beginMolecule(i); mol != NULL;
138 mol = info_->nextMolecule(i)) {
139 for (sd = mol->beginIntegrableObject(j); sd != NULL;
140 sd = mol->nextIntegrableObject(j)) {
144 this->getPosScale(pos, COM, index, sc);
146 pos = oldPos[index] + dt * (vel + sc);
153 rattle_->constraintA();
163 void NPA::moveB(
void) {
164 SimInfo::MoleculeIterator i;
165 Molecule::IntegrableObjectIterator j;
180 for (mol = info_->beginMolecule(i); mol != NULL;
181 mol = info_->nextMolecule(i)) {
182 for (sd = mol->beginIntegrableObject(j); sd != NULL;
183 sd = mol->nextIntegrableObject(j)) {
184 oldVel[index] = sd->getVel();
186 if (sd->isDirectional()) oldJi[index] = sd->getJ();
192 instaVol = thermo.getVolume();
193 for (
int k = 0; k < maxIterNum_; k++) {
194 instaTemp = thermo.getTemperature();
195 instaPress = thermo.getPressure();
199 this->calcVelScale();
202 for (mol = info_->beginMolecule(i); mol != NULL;
203 mol = info_->nextMolecule(i)) {
204 for (sd = mol->beginIntegrableObject(j); sd != NULL;
205 sd = mol->nextIntegrableObject(j)) {
207 mass = sd->getMass();
209 getVelScaleB(sc, index);
212 vel = oldVel[index] + dt2 * Constants::energyConvert / mass * frc -
217 if (sd->isDirectional()) {
219 Tb = sd->lab2Body(sd->getTrq());
221 ji = oldJi[index] + dt2 * Constants::energyConvert * Tb;
230 rattle_->constraintB();
232 if (this->etaConverged())
break;
239 void NPA::evolveEtaA() {
240 eta(2, 2) += dt2 * instaVol *
241 (press(2, 2) - targetPressure / Constants::pressureConvert) /
246 void NPA::evolveEtaB() {
251 (press(2, 2) - targetPressure / Constants::pressureConvert) /
255 void NPA::calcVelScale() {
256 for (
int i = 0; i < 3; i++) {
257 for (
int j = 0; j < 3; j++) {
258 vScale(i, j) = eta(i, j);
263 void NPA::getVelScaleA(Vector3d& sc,
const Vector3d& vel) {
267 void NPA::getVelScaleB(Vector3d& sc,
int index) {
268 sc = vScale * oldVel[index];
271 void NPA::getPosScale(
const Vector3d& pos,
const Vector3d& COM,
int index,
273 Vector3d rj = (oldPos[index] + pos) / (RealType)2.0 - COM;
277 void NPA::scaleSimBox() {
280 for (
int i = 0; i < 3; i++) {
281 for (
int j = 0; j < 3; j++) {
282 scaleMat(i, j) = 0.0;
283 if (i == j) { scaleMat(i, j) = 1.0; }
287 scaleMat(2, 2) = exp(dt * eta(2, 2));
288 Mat3x3d hmat = snap->getHmat();
289 hmat = hmat * scaleMat;
293 bool NPA::etaConverged() {
295 RealType diffEta, sumEta;
298 for (i = 0; i < 3; i++) {
299 sumEta += pow(prevEta(i, i) - eta(i, i), 2);
302 diffEta = sqrt(sumEta / 3.0);
304 return (diffEta <= etaTolerance);
307 RealType NPA::calcConservedQuantity() {
313 NkBT = info_->getNGlobalIntegrableObjects() * Constants::kB * targetTemp;
315 RealType conservedQuantity;
316 RealType totalEnergy;
317 RealType barostat_kinetic;
318 RealType barostat_potential;
321 totalEnergy = thermo.getTotalEnergy();
323 SquareMatrix<RealType, 3> tmp = eta.transpose() * eta;
326 barostat_kinetic = NkBT * tb2 * trEta / (2.0 * Constants::energyConvert);
329 (targetPressure * thermo.getVolume() / Constants::pressureConvert) /
330 Constants::energyConvert;
332 conservedQuantity = totalEnergy + barostat_kinetic + barostat_potential;
334 return conservedQuantity;
337 void NPA::loadEta() { eta = snap->getBarostat(); }
339 void NPA::saveEta() { snap->setBarostat(eta); }
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.