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

Comparing trunk/src/flucq/FluctuatingChargeConstraints.cpp (file contents):
Revision 1879 by gezelter, Sun Jun 16 15:15:42 2013 UTC vs.
Revision 1915 by gezelter, Mon Jul 29 17:55:17 2013 UTC

# Line 50 | Line 50 | namespace OpenMD {
50   namespace OpenMD {
51  
52    FluctuatingChargeConstraints::FluctuatingChargeConstraints(SimInfo* info) :
53 <    info_(info), hasFlucQ_(false) {
53 >    info_(info), constrainRegions_(false), hasFlucQ_(false), initialized_(false) {
54      
55 <    if (info_->usesFluctuatingCharges()) {
56 <      if (info_->getNFluctuatingCharges() > 0) {
57 <        hasFlucQ_ = true;
55 >  }
56 >
57 >  void FluctuatingChargeConstraints::initialize(){
58 >    if(info_->usesFluctuatingCharges()){
59 >      if(info_->getNFluctuatingCharges() > 0){
60 >        hasFlucQ_ = true;
61        }
62      }
63 +    initialized_ = true;
64    }
65  
66 +
67 +  void FluctuatingChargeConstraints::setConstrainRegions(bool cr) {
68 +    constrainRegions_ = cr;
69 +
70 +    if (!initialized_) initialize();
71 +
72 +    regionKeys_.clear();
73 +    regionForce_.clear();
74 +    regionCharges_.clear();
75 +
76 +    if (constrainRegions_) {
77 +      SimInfo::MoleculeIterator i;
78 +      Molecule* mol;
79 +      int reg;
80 +      std::set<int> regions;      
81 +
82 +      for (mol = info_->beginMolecule(i); mol != NULL;
83 +           mol = info_->nextMolecule(i)) {
84 +        reg = mol->getRegion();
85 +        if (reg >= 0) regions.insert(reg);
86 +      }
87 +      // resize the keys vector to the largest found value for regions.
88 +      regionKeys_.resize( *(regions.end()) );
89 +      int which = 0;
90 +      for (std::set<int>::iterator r=regions.begin(); r!=regions.end(); ++r) {
91 +        regionKeys_[ (*r) ] = which;
92 +        which++;
93 +      }
94 +      regionForce_.resize( regionKeys_.size() );
95 +      regionCharges_.resize( regionKeys_.size() );
96 +    }
97 +  }
98 +
99 +
100    void FluctuatingChargeConstraints::applyConstraints() {
101 +    if (!initialized_) initialize();
102      if (!hasFlucQ_) return;
64    
103      SimInfo::MoleculeIterator i;
104      Molecule::FluctuatingChargeIterator  j;
105      Molecule* mol;
106      Atom* atom;
107      
108 <    RealType totalFrc, totalMolFrc, constrainedFrc;
71 <    
108 >    RealType totalFrc, totalMolFrc, regionFrc, constrainedFrc;
109      // accumulate the total system fluctuating charge forces
110      totalFrc = 0.0;
111 +    if (constrainRegions_) {
112 +      std::fill(regionForce_.begin(), regionForce_.end(), 0.0);
113 +      std::fill(regionCharges_.begin(), regionCharges_.end(), 0);
114 +    }
115  
116      for (mol = info_->beginMolecule(i); mol != NULL;
117           mol = info_->nextMolecule(i)) {
118  
119 +      int region = mol->getRegion();
120 +          
121        for (atom = mol->beginFluctuatingCharge(j); atom != NULL;
122             atom = mol->nextFluctuatingCharge(j)) {
80        totalFrc += atom->getFlucQFrc();
81      }
123  
124 +        RealType frc = atom->getFlucQFrc();
125 +        totalFrc += frc;
126 +        if (constrainRegions_) {
127 +          if (region >= 0) {        
128 +            regionForce_[regionKeys_[region]] += frc;
129 +            regionCharges_[regionKeys_[region]] += 1;
130 +          }
131 +        }
132 +      }
133      }
134  
135   #ifdef IS_MPI
# Line 87 | Line 137 | namespace OpenMD {
137      // processors:
138      MPI::COMM_WORLD.Allreduce(MPI::IN_PLACE, &totalFrc, 1, MPI::REALTYPE,
139                                MPI::SUM);
140 +
141 +    if (constrainRegions_) {
142 +      MPI::COMM_WORLD.Allreduce(MPI::IN_PLACE, &regionForce_[0],
143 +                                regionForce_.size(), MPI::REALTYPE, MPI::SUM);
144 +      MPI::COMM_WORLD.Allreduce(MPI::IN_PLACE, &regionCharges_[0],
145 +                                regionCharges_.size(), MPI::INT, MPI::SUM);
146 +    }
147 +
148   #endif
149 <
149 >
150      // divide by the total number of fluctuating charges:
151      totalFrc /= info_->getNFluctuatingCharges();
152 +    
153 +    // do the same in the regions:
154 +    if (constrainRegions_) {
155 +      for (int i = 0; i < regionForce_.size(); ++i)  {
156 +        regionForce_[ i ] /= regionCharges_[ i ];
157 +      }
158 +    }
159  
160      for (mol = info_->beginMolecule(i); mol != NULL;
161           mol = info_->nextMolecule(i)) {    
162        
163 <      totalMolFrc = 0.0;
163 >      if (constrainRegions_) {
164 >        int region = mol->getRegion();
165 >        if (region >= 0)
166 >          regionFrc = regionForce_[regionKeys_[region]];
167 >        else
168 >          regionFrc = 0.0;
169 >      } else {
170 >        regionFrc = 0.0;
171 >      }
172  
173 +      totalMolFrc = 0.0;
174 +      
175        // molecular constraints can be done with a second loop.
176        if (mol->constrainTotalCharge()) {
177          for (atom = mol->beginFluctuatingCharge(j); atom != NULL;
# Line 109 | Line 184 | namespace OpenMD {
184        for (atom = mol->beginFluctuatingCharge(j); atom != NULL;
185             atom = mol->nextFluctuatingCharge(j)) {
186          //constrainedFrc = atom->getFlucQFrc() - totalFrc - totalMolFrc;
187 +
188          constrainedFrc = atom->getFlucQFrc() - totalMolFrc;
189 +
190 +        if (constrainRegions_)
191 +          constrainedFrc -= regionFrc;
192 +        
193          atom->setFlucQFrc(constrainedFrc);
194        }      
195      }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines