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 2026 by gezelter, Wed Oct 22 12:23:59 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 UniformField::initialize() {
61  
62 <  void ElectricField::initialize() {
62 >    std::vector<RealType> ef;
63 >
64      if (simParams->haveElectricField()) {
65 <      doElectricField = true;
66 <      EF = simParams->getElectricField();
65 >      doUniformField = true;
66 >      ef = simParams->getElectricField();            
67      }  
68 +    if (simParams->haveUniformField()) {
69 +      doUniformField = true;
70 +      ef = simParams->getUniformField();
71 +    }  
72 +    if (ef.size() != 3) {
73 +      sprintf(painCave.errMsg,
74 +              "UniformField: Incorrect number of parameters specified.\n"
75 +              "\tthere should be 3 parameters, but %lu were specified.\n", ef.size());
76 +      painCave.isFatal = 1;
77 +      simError();      
78 +    }
79 +    EF.x() = ef[0];
80 +    EF.y() = ef[1];
81 +    EF.z() = ef[2];
82 +
83      int storageLayout_ = info_->getSnapshotManager()->getStorageLayout();
84      if (storageLayout_ & DataStorage::dslParticlePot) doParticlePot = true;
85      initialized = true;
86    }
87 +  
88 +  void UniformField::applyPerturbation() {
89  
68  void ElectricField::applyPerturbation() {
90      if (!initialized) initialize();
91  
92      SimInfo::MoleculeIterator i;
93      Molecule::AtomIterator  j;
94      Molecule* mol;
95      Atom* atom;
96 +    AtomType* atype;
97      potVec longRangePotential(0.0);
98 <    Vector3d dip;
99 <    Vector3d trq;
100 <    Vector3d EFfrc;                            
101 <    Vector3d pos;
102 <    RealType chrg;
103 <    RealType pot, fieldPot, moment;
104 <    RealType chrgToKcal = 23.0609;
105 <    RealType debyeToKcal = 4.8018969509;
98 >
99 >    RealType C;
100 >    Vector3d D;
101 >    RealType U;
102 >    RealType fPot;
103 >    Vector3d t;
104 >    Vector3d f;
105 >    Vector3d r;
106 >
107      bool isCharge;
108  
109 <    if (doElectricField) {
87 <      fieldPot = 0.0;
109 >    if (doUniformField) {
110  
111 <      for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) {      
111 >      U = 0.0;
112 >      fPot = 0.0;
113 >
114 >      for (mol = info_->beginMolecule(i); mol != NULL;
115 >           mol = info_->nextMolecule(i)) {      
116 >
117          for (atom = mol->beginAtom(j); atom != NULL;
118               atom = mol->nextAtom(j)) {
92          isCharge = false;
93          chrg = 0.0;
119  
120 <          FixedChargeAdapter fca = FixedChargeAdapter(atom->getAtomType());
120 >          isCharge = false;
121 >          C = 0.0;
122 >          
123 >          atype = atom->getAtomType();
124 >
125 >          // ad-hoc choice of the origin for potential calculation and
126 >          // fluctuating charge force:
127 >
128 >          r = atom->getPos();
129 >          
130 >          if (atype->isElectrostatic()) {
131 >            atom->addElectricField(EF * PhysicalConstants::chargeFieldConvert);
132 >          }
133 >          
134 >          FixedChargeAdapter fca = FixedChargeAdapter(atype);
135            if ( fca.isFixedCharge() ) {
136              isCharge = true;
137 <            chrg = fca.getCharge();
137 >            C = fca.getCharge();
138            }
139            
140 <          FluctuatingChargeAdapter fqa = FluctuatingChargeAdapter(atom->getAtomType());
140 >          FluctuatingChargeAdapter fqa = FluctuatingChargeAdapter(atype);
141            if ( fqa.isFluctuatingCharge() ) {
142              isCharge = true;
143 <            chrg += atom->getFlucQPos();
143 >            C += atom->getFlucQPos();
144 >            atom->addFlucQFrc( dot(r, EF)
145 >                               * PhysicalConstants::chargeFieldConvert );
146            }
147            
148            if (isCharge) {
149 <            EFfrc = EF*chrg;
150 <            EFfrc *= chrgToKcal;
151 <            atom->addFrc(EFfrc);
152 <            // totally ad-hoc choice of the origin for potential calculation
112 <            pos = atom->getPos();
113 <            pot = -dot(pos, EFfrc);
149 >            f = EF * C * PhysicalConstants::chargeFieldConvert;
150 >            atom->addFrc(f);
151 >            U = -dot(r, f);
152 >
153              if (doParticlePot) {      
154 <              atom->addParticlePot(pot);
154 >              atom->addParticlePot(U);
155              }
156 <            fieldPot += pot;
156 >            fPot += U;
157            }
158              
159 <          MultipoleAdapter ma = MultipoleAdapter(atom->getAtomType());
159 >          MultipoleAdapter ma = MultipoleAdapter(atype);
160            if (ma.isDipole() ) {
161 <            Vector3d u_i = atom->getElectroFrame().getColumn(2);
162 <            moment = ma.getDipoleMoment();
163 <            moment *= debyeToKcal;
164 <            dip = u_i * moment;
165 <            trq = cross(dip, EF);
166 <            //cerr << "dip = " << dip << "\n";
167 <            // cerr << "trq = " << trq << "\n";
168 <            atom->addTrq(trq);
130 <            pot = -dot(dip, EF);
131 <            //cerr << "pot = " << pot << "\n";
161 >
162 >            D = atom->getDipole() * PhysicalConstants::dipoleFieldConvert;
163 >            
164 >            t = cross(D, EF);
165 >            atom->addTrq(t);
166 >
167 >            U = -dot(D, EF);
168 >
169              if (doParticlePot) {      
170 <              atom->addParticlePot(pot);
170 >              atom->addParticlePot(U);
171              }
172 <            fieldPot += pot;
172 >            fPot += U;
173            }
174          }
175        }
176 +
177   #ifdef IS_MPI
178 <      MPI::COMM_WORLD.Allreduce(MPI::IN_PLACE, &fieldPot, 1, MPI::REALTYPE,
179 <                                MPI::SUM);
178 >      MPI_Allreduce(MPI_IN_PLACE, &fPot, 1, MPI_REALTYPE,
179 >                    MPI_SUM, MPI_COMM_WORLD);
180   #endif
181 +
182        Snapshot* snap = info_->getSnapshotManager()->getCurrentSnapshot();
183        longRangePotential = snap->getLongRangePotentials();
184 <      // << "longRangePotential = " << longRangePotential << "\n";
146 <      longRangePotential[ELECTROSTATIC_FAMILY] += fieldPot;
147 <      //cerr << "longRangePotential[ELECTROSTATIC_FAMILY] = " << longRangePotential[ELECTROSTATIC_FAMILY] << "\n";
184 >      longRangePotential[ELECTROSTATIC_FAMILY] += fPot;
185        snap->setLongRangePotential(longRangePotential);
186      }
187    }
151
188   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines