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

Comparing:
trunk/src/perturbations/ElectricField.cpp (file contents), Revision 1908 by gezelter, Fri Jul 19 21:25:45 2013 UTC vs.
trunk/src/perturbations/UniformField.cpp (file contents), Revision 2026 by gezelter, Wed Oct 22 12:23:59 2014 UTC

# Line 39 | Line 39
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);
76    Vector3d dip;
77    Vector3d trq;
78    Vector3d EFfrc;                            
79    Vector3d pos;
98  
99 <    if (doElectricField) {
100 <      const RealType chrgToKcal = 23.0609;
101 <      const RealType debyeToKcal = 4.8018969509;
102 <      RealType pot;
103 <      RealType fieldPot = 0.0;
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 (doUniformField) {
110 +
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)) {
119  
120 <          bool isCharge = false;
121 <          RealType chrg = 0.0;
120 >          isCharge = false;
121 >          C = 0.0;
122            
123 <          AtomType* atype = atom->getAtomType();
123 >          atype = atom->getAtomType();
124  
125            // ad-hoc choice of the origin for potential calculation and
126            // fluctuating charge force:
127 <          pos = atom->getPos();
127 >
128 >          r = atom->getPos();
129            
130            if (atype->isElectrostatic()) {
131 <            atom->addElectricField(EF * chrgToKcal);
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(atype);
141            if ( fqa.isFluctuatingCharge() ) {
142              isCharge = true;
143 <            chrg += atom->getFlucQPos();
144 <            atom->addFlucQFrc( dot(pos,EF) * chrgToKcal );
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 <            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(atype);
159 >          MultipoleAdapter ma = MultipoleAdapter(atype);
160            if (ma.isDipole() ) {
132            Vector3d dipole = atom->getDipole();
133            dipole *= debyeToKcal;
161  
162 <            trq = cross(dipole, EF);
163 <            atom->addTrq(trq);
162 >            D = atom->getDipole() * PhysicalConstants::dipoleFieldConvert;
163 >            
164 >            t = cross(D, EF);
165 >            atom->addTrq(t);
166  
167 <            pot = -dot(dipole, EF);
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[ELECTROSTATIC_FAMILY] += fieldPot;
184 >      longRangePotential[ELECTROSTATIC_FAMILY] += fPot;
185        snap->setLongRangePotential(longRangePotential);
186      }
187    }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines