ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/perturbations/UniformField.cpp
(Generate patch)

Comparing:
branches/development/src/perturbations/ElectricField.cpp (file contents), Revision 1780 by jmarr, Mon Aug 20 18:28:22 2012 UTC vs.
trunk/src/perturbations/UniformField.cpp (file contents), Revision 2020 by gezelter, Mon Sep 22 19:18:35 2014 UTC

# Line 35 | Line 35
35   *                                                                      
36   * [1]  Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).            
37   * [2]  Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).          
38 < * [3]  Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008).          
38 > * [3]  Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).          
39   * [4]  Kuang & Gezelter,  J. Chem. Phys. 133, 164101 (2010).
40   * [5]  Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41   */
42 < #include "perturbations/ElectricField.hpp"
42 >
43 > #include "perturbations/UniformField.hpp"
44   #include "types/FixedChargeAdapter.hpp"
45   #include "types/FluctuatingChargeAdapter.hpp"
46   #include "types/MultipoleAdapter.hpp"
47   #include "primitives/Molecule.hpp"
48   #include "nonbonded/NonBondedInteraction.hpp"
49 + #include "utils/PhysicalConstants.hpp"
50  
51   namespace OpenMD {
52 <
53 <  ElectricField::ElectricField(SimInfo* info) : info_(info),
54 <                                                doElectricField(false),
55 <                                                doParticlePot(false),
56 <                                                initialized(false) {
52 >  
53 >  UniformField::UniformField(SimInfo* info) : info_(info),
54 >                                            doUniformField(false),
55 >                                            doParticlePot(false),
56 >                                            initialized(false) {
57      simParams = info_->getSimParams();
58    }
59 <
60 <  void ElectricField::initialize() {
59 >  
60 >  void UniformField::initialize() {
61      if (simParams->haveElectricField()) {
62 <      doElectricField = true;
62 >      doUniformField = true;
63        EF = simParams->getElectricField();
64      }  
65 +    if (simParams->haveUniformField()) {
66 +      doUniformField = true;
67 +      EF = simParams->getUniformField();
68 +    }  
69      int storageLayout_ = info_->getSnapshotManager()->getStorageLayout();
70      if (storageLayout_ & DataStorage::dslParticlePot) doParticlePot = true;
71      initialized = true;
72    }
73 +  
74 +  void UniformField::applyPerturbation() {
75  
68  void ElectricField::applyPerturbation() {
76      if (!initialized) initialize();
77  
78      SimInfo::MoleculeIterator i;
79      Molecule::AtomIterator  j;
80      Molecule* mol;
81      Atom* atom;
82 +    AtomType* atype;
83      potVec longRangePotential(0.0);
84 <    Vector3d dip;
85 <    Vector3d trq;
86 <    Vector3d EFfrc;                            
87 <    Vector3d pos;
88 <    RealType chrg;
89 <    RealType pot, fieldPot, moment;
90 <    RealType chrgToKcal = 23.0609;
91 <    RealType debyeToKcal = 4.8018969509;
84 >
85 >    RealType C;
86 >    Vector3d D;
87 >    RealType U;
88 >    RealType fPot;
89 >    Vector3d t;
90 >    Vector3d f;
91 >    Vector3d r;
92 >
93      bool isCharge;
94  
95 <    if (doElectricField) {
87 <      fieldPot = 0.0;
95 >    if (doUniformField) {
96  
97 <      for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) {      
97 >      U = 0.0;
98 >      fPot = 0.0;
99 >
100 >      for (mol = info_->beginMolecule(i); mol != NULL;
101 >           mol = info_->nextMolecule(i)) {      
102 >
103          for (atom = mol->beginAtom(j); atom != NULL;
104               atom = mol->nextAtom(j)) {
92          isCharge = false;
93          chrg = 0.0;
105  
106 <          FixedChargeAdapter fca = FixedChargeAdapter(atom->getAtomType());
106 >          isCharge = false;
107 >          C = 0.0;
108 >          
109 >          atype = atom->getAtomType();
110 >
111 >          // ad-hoc choice of the origin for potential calculation and
112 >          // fluctuating charge force:
113 >
114 >          r = atom->getPos();
115 >          
116 >          if (atype->isElectrostatic()) {
117 >            atom->addElectricField(EF * PhysicalConstants::chargeFieldConvert);
118 >          }
119 >          
120 >          FixedChargeAdapter fca = FixedChargeAdapter(atype);
121            if ( fca.isFixedCharge() ) {
122              isCharge = true;
123 <            chrg = fca.getCharge();
123 >            C = fca.getCharge();
124            }
125            
126 <          FluctuatingChargeAdapter fqa = FluctuatingChargeAdapter(atom->getAtomType());
126 >          FluctuatingChargeAdapter fqa = FluctuatingChargeAdapter(atype);
127            if ( fqa.isFluctuatingCharge() ) {
128              isCharge = true;
129 <            chrg += atom->getFlucQPos();
129 >            C += atom->getFlucQPos();
130 >            atom->addFlucQFrc( dot(r, EF)
131 >                               * PhysicalConstants::chargeFieldConvert );
132            }
133            
134            if (isCharge) {
135 <            EFfrc = EF*chrg;
136 <            EFfrc *= chrgToKcal;
137 <            atom->addFrc(EFfrc);
138 <            // totally ad-hoc choice of the origin for potential calculation
112 <            pos = atom->getPos();
113 <            pot = -dot(pos, EFfrc);
135 >            f = EF * C * PhysicalConstants::chargeFieldConvert;
136 >            atom->addFrc(f);
137 >            U = -dot(r, f);
138 >
139              if (doParticlePot) {      
140 <              atom->addParticlePot(pot);
140 >              atom->addParticlePot(U);
141              }
142 <            fieldPot += pot;
142 >            fPot += U;
143            }
144              
145 <          MultipoleAdapter ma = MultipoleAdapter(atom->getAtomType());
145 >          MultipoleAdapter ma = MultipoleAdapter(atype);
146            if (ma.isDipole() ) {
147 <            Vector3d u_i = atom->getElectroFrame().getColumn(2);
148 <            moment = ma.getDipoleMoment();
149 <            moment *= debyeToKcal;
150 <            dip = u_i * moment;
151 <            trq = cross(dip, EF);
152 <            //cerr << "dip = " << dip << "\n";
153 <            // cerr << "trq = " << trq << "\n";
154 <            atom->addTrq(trq);
130 <            pot = -dot(dip, EF);
131 <            //cerr << "pot = " << pot << "\n";
147 >
148 >            D = atom->getDipole() * PhysicalConstants::dipoleFieldConvert;
149 >            
150 >            t = cross(D, EF);
151 >            atom->addTrq(t);
152 >
153 >            U = -dot(D, EF);
154 >
155              if (doParticlePot) {      
156 <              atom->addParticlePot(pot);
156 >              atom->addParticlePot(U);
157              }
158 <            fieldPot += pot;
158 >            fPot += U;
159            }
160          }
161        }
162 +
163   #ifdef IS_MPI
164 <      MPI::COMM_WORLD.Allreduce(MPI::IN_PLACE, &fieldPot, 1, MPI::REALTYPE,
165 <                                MPI::SUM);
164 >      MPI_Allreduce(MPI_IN_PLACE, &fPot, 1, MPI_REALTYPE,
165 >                    MPI_SUM, MPI_COMM_WORLD);
166   #endif
167 +
168        Snapshot* snap = info_->getSnapshotManager()->getCurrentSnapshot();
169        longRangePotential = snap->getLongRangePotentials();
170 <      // << "longRangePotential = " << longRangePotential << "\n";
146 <      longRangePotential[ELECTROSTATIC_FAMILY] += fieldPot;
147 <      //cerr << "longRangePotential[ELECTROSTATIC_FAMILY] = " << longRangePotential[ELECTROSTATIC_FAMILY] << "\n";
170 >      longRangePotential[ELECTROSTATIC_FAMILY] += fPot;
171        snap->setLongRangePotential(longRangePotential);
172      }
173    }
151
174   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines