| 302 |  | /**@todo need refactorying*/ | 
| 303 |  | //Conserved Quantity is set by integrator and time is set by setTime | 
| 304 |  |  | 
| 305 | + | } | 
| 306 | + |  | 
| 307 | + |  | 
| 308 | + |  | 
| 309 | + | Vector3d Thermo::getBoxDipole() { | 
| 310 | + | Snapshot* currSnapshot = info_->getSnapshotManager()->getCurrentSnapshot(); | 
| 311 | + | SimInfo::MoleculeIterator miter; | 
| 312 | + | std::vector<Atom*>::iterator aiter; | 
| 313 | + | Molecule* mol; | 
| 314 | + | Atom* atom; | 
| 315 | + | RealType charge; | 
| 316 | + | RealType moment(0.0); | 
| 317 | + | Vector3d ri(0.0); | 
| 318 | + | Vector3d dipoleVector(0.0); | 
| 319 | + | Vector3d nPos(0.0); | 
| 320 | + | Vector3d pPos(0.0); | 
| 321 | + | RealType nChg(0.0); | 
| 322 | + | RealType pChg(0.0); | 
| 323 | + | int nCount = 0; | 
| 324 | + | int pCount = 0; | 
| 325 | + |  | 
| 326 | + | RealType chargeToC = 1.60217733e-19; | 
| 327 | + | RealType angstromToM = 1.0e-10;    RealType debyeToCm = 3.33564095198e-30; | 
| 328 | + |  | 
| 329 | + | for (mol = info_->beginMolecule(miter); mol != NULL; | 
| 330 | + | mol = info_->nextMolecule(miter)) { | 
| 331 | + |  | 
| 332 | + | for (atom = mol->beginAtom(aiter); atom != NULL; | 
| 333 | + | atom = mol->nextAtom(aiter)) { | 
| 334 | + |  | 
| 335 | + | if (atom->isCharge() ) { | 
| 336 | + | charge = 0.0; | 
| 337 | + | GenericData* data = atom->getAtomType()->getPropertyByName("Charge"); | 
| 338 | + | if (data != NULL) { | 
| 339 | + |  | 
| 340 | + | charge = (dynamic_cast<DoubleGenericData*>(data))->getData(); | 
| 341 | + | charge *= chargeToC; | 
| 342 | + |  | 
| 343 | + | ri = atom->getPos(); | 
| 344 | + | currSnapshot->wrapVector(ri); | 
| 345 | + | ri *= angstromToM; | 
| 346 | + |  | 
| 347 | + | if (charge < 0.0) { | 
| 348 | + | nPos += ri; | 
| 349 | + | nChg -= charge; | 
| 350 | + | nCount++; | 
| 351 | + | } else if (charge > 0.0) { | 
| 352 | + | pPos += ri; | 
| 353 | + | pChg += charge; | 
| 354 | + | pCount++; | 
| 355 | + | } | 
| 356 | + | } | 
| 357 | + | } | 
| 358 | + |  | 
| 359 | + | if (atom->isDipole() ) { | 
| 360 | + | Vector3d u_i = atom->getElectroFrame().getColumn(2); | 
| 361 | + | GenericData* data = dynamic_cast<DirectionalAtomType*>(atom->getAtomType())->getPropertyByName("Dipole"); | 
| 362 | + | if (data != NULL) { | 
| 363 | + | moment = (dynamic_cast<DoubleGenericData*>(data))->getData(); | 
| 364 | + |  | 
| 365 | + | moment *= debyeToCm; | 
| 366 | + | dipoleVector += u_i * moment; | 
| 367 | + | } | 
| 368 | + | } | 
| 369 | + | } | 
| 370 | + | } | 
| 371 | + |  | 
| 372 | + |  | 
| 373 | + | #ifdef IS_MPI | 
| 374 | + | RealType pChg_global, nChg_global; | 
| 375 | + | int pCount_global, nCount_global; | 
| 376 | + | Vector3d pPos_global, nPos_global, dipVec_global; | 
| 377 | + |  | 
| 378 | + | MPI_Allreduce(&pChg, &pChg_global, 1, MPI_REALTYPE, MPI_SUM, | 
| 379 | + | MPI_COMM_WORLD); | 
| 380 | + | pChg = pChg_global; | 
| 381 | + | MPI_Allreduce(&nChg, &nChg_global, 1, MPI_REALTYPE, MPI_SUM, | 
| 382 | + | MPI_COMM_WORLD); | 
| 383 | + | nChg = nChg_global; | 
| 384 | + | MPI_Allreduce(&pCount, &pCount_global, 1, MPI_INTEGER, MPI_SUM, | 
| 385 | + | MPI_COMM_WORLD); | 
| 386 | + | pCount = pCount_global; | 
| 387 | + | MPI_Allreduce(&nCount, &nCount_global, 1, MPI_INTEGER, MPI_SUM, | 
| 388 | + | MPI_COMM_WORLD); | 
| 389 | + | nCount = nCount_global; | 
| 390 | + | MPI_Allreduce(pPos.getArrayPointer(), pPos_global.getArrayPointer(), 3, | 
| 391 | + | MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD); | 
| 392 | + | pPos = pPos_global; | 
| 393 | + | MPI_Allreduce(nPos.getArrayPointer(), nPos_global.getArrayPointer(), 3, | 
| 394 | + | MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD); | 
| 395 | + | nPos = nPos_global; | 
| 396 | + | MPI_Allreduce(dipoleVector.getArrayPointer(), | 
| 397 | + | dipVec_global.getArrayPointer(), 3, | 
| 398 | + | MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD); | 
| 399 | + | dipoleVector = dipVec_global; | 
| 400 | + | #endif //is_mpi | 
| 401 | + |  | 
| 402 | + | // first load the accumulated dipole moment (if dipoles were present) | 
| 403 | + | Vector3d boxDipole = dipoleVector; | 
| 404 | + | // now include the dipole moment due to charges | 
| 405 | + | // use the lesser of the positive and negative charge totals | 
| 406 | + | RealType chg_value = nChg <= pChg ? nChg : pChg; | 
| 407 | + |  | 
| 408 | + | // find the average positions | 
| 409 | + | if (pCount > 0 && nCount > 0 ) { | 
| 410 | + | pPos /= pCount; | 
| 411 | + | nPos /= nCount; | 
| 412 | + | } | 
| 413 | + |  | 
| 414 | + | // dipole is from the negative to the positive (physics notation) | 
| 415 | + | boxDipole += (pPos - nPos) * chg_value; | 
| 416 | + |  | 
| 417 | + | return boxDipole; | 
| 418 |  | } | 
| 419 |  |  | 
| 420 | + |  | 
| 421 |  | } //end namespace OpenMD |