ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/OOPSEMinimizerBase.cpp
(Generate patch)

Comparing trunk/OOPSE/libmdtools/OOPSEMinimizerBase.cpp (file contents):
Revision 1031 by tim, Fri Feb 6 18:58:06 2004 UTC vs.
Revision 1057 by tim, Tue Feb 17 19:23:44 2004 UTC

# Line 1 | Line 1
1 < #include "Integrator.hpp"
2 <
3 < OOPSEMinimizerBase::OOPSEMinimizerBase(SimInfo* theInfo, ForceFields* the_ff)
4 <                           : RealIntegrator( theInfo, the_ff ){
5 <  tStats = new Thermo(info);
6 <  dumpOut = new DumpWriter(info);
7 <  calcDim();
8 < }
9 <
10 < OOPSEMinimizerBase::~OOPSEMinimizerBase(){
11 <  delete tStats;
12 <  delete dumpOut;
13 < }
14 <
15 < /**
16 < *
17 < */
18 <
19 <
20 < double OOPSEMinimizerBase::calcGradient(vector<double>& x, vector<double>& grad){
21 <  Atom** atoms;  
22 <  DirectionalAtom* dAtom;
23 <  int index;
24 <  double force[3];
25 <  double dAtomGrad[6];
26 <
27 <  setOptCoor(x);
28 <
29 <  atoms = this->atoms;
30 <  index = 0;
31 <
32 <  for(int i = 0; i < nAtoms; i++){
33 <
34 <    if(atoms[i]->isDirectional()){
35 <      dAtom = (DirectionalAtom*) atoms[i];
36 <      dAtom->getGrad(dAtomGrad);
37 <
38 <      grad[index++] = dAtomGrad[0];
39 <      grad[index++] = dAtomGrad[1];
40 <      grad[index++] = dAtomGrad[2];
41 <      grad[index++] = dAtomGrad[3];
42 <      grad[index++] = dAtomGrad[4];
43 <      grad[index++] = dAtomGrad[5];
44 <
45 <    }
46 <    else{
47 <      atoms[i]->getFrc(force);
48 <
49 <      grad[index++] = force[0];
50 <      grad[index++] = force[1];
51 <      grad[index++] = force[2];
52 <
53 <    }
54 <    
55 <  }
56 <
57 <  return tStats->getPotential();
58 <  
59 < }
60 <
61 < /**
62 < *
63 < */
64 <
65 < void OOPSEMinimizerBase::setOptCoor(vector<double>& x){
66 <  Atom** atoms;  
67 <  DirectionalAtom* dAtom;
68 <  int index;
69 <  double position[3];
70 <  double eulerAngle[3];
71 <
72 <  atoms = this->atoms;
73 <  index = 0;
74 <  
75 <  for(int i = 0; i < nAtoms; i++){
76 <    
77 <    position[0] = x[index++];
78 <    position[1] = x[index++];
79 <    position[2] = x[index++];
80 <
81 <    atoms[i]->setPos(position);
82 <
83 <    if (atoms[i]->isDirectional()){
84 <      dAtom = (DirectionalAtom*) atoms[i];
85 <
86 <      eulerAngle[0] = x[index++];
87 <      eulerAngle[1] = x[index++];
88 <      eulerAngle[2] = x[index++];
89 <
90 <       dAtom->setEuler(eulerAngle[0], eulerAngle[1], eulerAngle[2]);
91 <
92 <    }
93 <    
94 <  }
95 <  
96 < }
97 <
98 < /**
99 < *
100 < */
101 < vector<double> OOPSEMinimizerBase::getOptCoor(){
102 <  Atom** atoms;  
103 <  DirectionalAtom* dAtom;
104 <  int index;
105 <  double position[3];
106 <  double eulerAngle[3];
107 <  vector<double> x;
108 <
109 <  x.resize(getDim());
110 <  atoms = this->atoms;
111 <  index = 0;
112 <  
113 <  for(int i = 0; i < nAtoms; i++){
114 <    atoms[i]->getPos(position);
115 <
116 <    x[index++] = position[0];
117 <    x[index++] = position[1];
118 <    x[index++] = position[2];
119 <
120 <    if (atoms[i]->isDirectional()){
121 <      dAtom = (DirectionalAtom*) atoms[i];
122 <      dAtom->getEulerAngles(eulerAngle);
123 <
124 <      x[index++] = eulerAngle[0];
125 <      x[index++] = eulerAngle[1];
126 <      x[index++] = eulerAngle[2];
127 <      
128 <    }
129 <    
130 <  }
131 <
132 <  return x;
133 <
134 < }
135 <        
136 < void OOPSEMinimizerBase::calcDim(){
137 <  Atom** atoms;  
138 <  DirectionalAtom* dAtom;
139 <  int dim;
140 <
141 <  dim = 0;
142 <
143 <  atoms = this->atoms;
144 <  
145 <  for(int i = 0; i < nAtoms; i++){
146 <    dim += 3;
147 <    if (atoms[i]->isDirectional())
148 <      dim += 3;      
149 <  }
150 <
151 < }
152 <
153 < void OOPSEMinimizerBase::output(vector<double>& x, int iteration){
154 <  setOptCoor(x);
155 <  dumpOut->writeDump(iteration);
156 < }
1 > #include "Integrator.hpp"
2 >
3 > OOPSEMinimizerBase::OOPSEMinimizerBase(SimInfo* theInfo, ForceFields* the_ff)
4 >                           : RealIntegrator( theInfo, the_ff ){
5 >  atoms = info->atoms;
6 >  tStats = new Thermo(info);
7 >  dumpOut = new DumpWriter(info);
8 >  statOut = new StatWriter(info);
9 >  calcDim();
10 >
11 >  //save the reference coordinate
12 >  RealIntegrator::preMove();
13 >  
14 > }
15 >
16 > OOPSEMinimizerBase::~OOPSEMinimizerBase(){
17 >  delete tStats;
18 >  delete dumpOut;
19 >  delete statOut;
20 > }
21 >
22 > /**
23 > *
24 > */
25 >
26 >
27 > double OOPSEMinimizerBase::calcGradient(vector<double>& x, vector<double>& grad){
28 >
29 >  DirectionalAtom* dAtom;
30 >  int index;
31 >  double force[3];
32 >  double dAtomGrad[6];
33 >
34 >  setCoor(x);
35 >
36 >  if (nConstrained){
37 >    shakeR();
38 >  }
39 >      
40 >  calcForce(1, 1);
41 >  
42 >  if (nConstrained){
43 >    shakeF();
44 >  }
45 >  
46 >  x = getCoor();
47 >  
48 >
49 >  index = 0;
50 >
51 >  for(int i = 0; i < nAtoms; i++){
52 >
53 >    if(atoms[i]->isDirectional()){
54 >      dAtom = (DirectionalAtom*) atoms[i];
55 >      dAtom->getGrad(dAtomGrad);
56 >
57 >      //gradient = du/dx = -f
58 >      grad[index++] = -dAtomGrad[0];
59 >      grad[index++] = -dAtomGrad[1];
60 >      grad[index++] = -dAtomGrad[2];
61 >      grad[index++] = -dAtomGrad[3];
62 >      grad[index++] = -dAtomGrad[4];
63 >      grad[index++] = -dAtomGrad[5];
64 >
65 >    }
66 >    else{
67 >      atoms[i]->getFrc(force);
68 >
69 >      grad[index++] = -force[0];
70 >      grad[index++] = -force[1];
71 >      grad[index++] = -force[2];
72 >
73 >    }
74 >    
75 >  }
76 >
77 >  return tStats->getPotential();
78 >  
79 > }
80 >
81 > /**
82 > *
83 > */
84 >
85 > void OOPSEMinimizerBase::setCoor(vector<double>& x){
86 >
87 >  DirectionalAtom* dAtom;
88 >  int index;
89 >  double position[3];
90 >  double eulerAngle[3];
91 >
92 >
93 >  index = 0;
94 >  
95 >  for(int i = 0; i < nAtoms; i++){
96 >    
97 >    position[0] = x[index++];
98 >    position[1] = x[index++];
99 >    position[2] = x[index++];
100 >
101 >    atoms[i]->setPos(position);
102 >
103 >    if (atoms[i]->isDirectional()){
104 >      dAtom = (DirectionalAtom*) atoms[i];
105 >
106 >      eulerAngle[0] = x[index++];
107 >      eulerAngle[1] = x[index++];
108 >      eulerAngle[2] = x[index++];
109 >
110 >       dAtom->setEuler(eulerAngle[0], eulerAngle[1], eulerAngle[2]);
111 >
112 >    }
113 >    
114 >  }
115 >  
116 > }
117 >
118 > /**
119 > *
120 > */
121 > vector<double> OOPSEMinimizerBase::getCoor(){
122 >
123 >  DirectionalAtom* dAtom;
124 >  int index;
125 >  double position[3];
126 >  double eulerAngle[3];
127 >  vector<double> x;
128 >
129 >  x.resize(getDim());
130 >
131 >  index = 0;
132 >  
133 >  for(int i = 0; i < nAtoms; i++){
134 >    atoms[i]->getPos(position);
135 >
136 >    x[index++] = position[0];
137 >    x[index++] = position[1];
138 >    x[index++] = position[2];
139 >
140 >    if (atoms[i]->isDirectional()){
141 >      dAtom = (DirectionalAtom*) atoms[i];
142 >      dAtom->getEulerAngles(eulerAngle);
143 >
144 >      x[index++] = eulerAngle[0];
145 >      x[index++] = eulerAngle[1];
146 >      x[index++] = eulerAngle[2];
147 >      
148 >    }
149 >    
150 >  }
151 >
152 >  return x;
153 >
154 > }
155 >        
156 > void OOPSEMinimizerBase::calcDim(){
157 >
158 >  DirectionalAtom* dAtom;
159 >
160 >  dim = 0;
161 >
162 >  for(int i = 0; i < nAtoms; i++){
163 >    dim += 3;
164 >    if (atoms[i]->isDirectional())
165 >      dim += 3;      
166 >  }
167 >
168 > }
169 >
170 > void OOPSEMinimizerBase::output(vector<double>& x, int iteration){
171 >  setCoor(x);
172 >  calcForce(1, 1);
173 >  dumpOut->writeDump(iteration);
174 >  statOut->writeStat(iteration);
175 > }
176 >
177 >
178 > //remove constraint force along the bond direction
179 > void OOPSEMinimizerBase::shakeF(){
180 >  int i, j;
181 >  int done;
182 >  double posA[3], posB[3];
183 >  double frcA[3], frcB[3];
184 >  double rab[3], fpab[3];
185 >  int a, b, ax, ay, az, bx, by, bz;
186 >  double rma, rmb;
187 >  double rvab;
188 >  double gab;
189 >  double rabsq;
190 >  double rfab;
191 >  int iteration;
192 >
193 >  for (i = 0; i < nAtoms; i++){
194 >    moving[i] = 0;
195 >    moved[i] = 1;
196 >  }
197 >
198 >  done = 0;
199 >  iteration = 0;
200 >  while (!done && (iteration < maxIteration)){
201 >    done = 1;
202 >
203 >    for (i = 0; i < nConstrained; i++){
204 >      a = constrainedA[i];
205 >      b = constrainedB[i];
206 >
207 >      ax = (a * 3) + 0;
208 >      ay = (a * 3) + 1;
209 >      az = (a * 3) + 2;
210 >
211 >      bx = (b * 3) + 0;
212 >      by = (b * 3) + 1;
213 >      bz = (b * 3) + 2;
214 >
215 >      if (moved[a] || moved[b]){
216 >
217 >        atoms[a]->getPos(posA);
218 >        atoms[b]->getPos(posB);
219 >
220 >        for (j = 0; j < 3; j++)
221 >          rab[j] = posA[j] - posB[j];
222 >
223 >        info->wrapVector(rab);
224 >
225 >        atoms[a]->getFrc(frcA);
226 >        atoms[b]->getFrc(frcB);
227 >
228 >        //rma = 1.0 / atoms[a]->getMass();
229 >        //rmb = 1.0 / atoms[b]->getMass();
230 >        rma = 1.0;
231 >        rmb = 1.0;
232 >        
233 >        
234 >        fpab[0] = frcA[0] * rma - frcB[0] * rmb;
235 >        fpab[1] = frcA[1] * rma - frcB[1] * rmb;
236 >        fpab[2] = frcA[2] * rma - frcB[2] * rmb;
237 >
238 >
239 >          gab=fpab[0] * fpab[0] + fpab[1] * fpab[1] + fpab[2] * fpab[2];
240 >          
241 >          if (gab < 1.0)
242 >            gab = 1.0;
243 >        
244 >          rabsq = rab[0] * rab[0] + rab[1] * rab[1] + rab[2] * rab[2];
245 >          rfab = rab[0] * fpab[0] + rab[1] * fpab[1] + rab[2] * fpab[2];
246 >
247 >          if (fabs(rfab) > sqrt(rabsq*gab) * 0.00001){
248 >
249 >            gab = -rfab /(rabsq*(rma + rmb));
250 >            
251 >            frcA[0] = rab[0] * gab;
252 >            frcA[1] = rab[1] * gab;
253 >            frcA[2] = rab[2] * gab;
254 >
255 >            atoms[a]->addFrc(frcA);
256 >            
257 >
258 >            frcB[0] = -rab[0] * gab;
259 >            frcB[1] = -rab[1] * gab;
260 >            frcB[2] = -rab[2] * gab;
261 >
262 >            atoms[b]->addFrc(frcB);
263 >          
264 >            moving[a] = 1;
265 >            moving[b] = 1;
266 >            done = 0;
267 >          }            
268 >      }
269 >    }
270 >
271 >    for (i = 0; i < nAtoms; i++){
272 >      moved[i] = moving[i];
273 >      moving[i] = 0;
274 >    }
275 >
276 >    iteration++;
277 >  }
278 >
279 > }
280 >
281 > void OOPSEMinimizerBase::shakeR(){
282 >  int i, j;
283 >  int done;
284 >  double posA[3], posB[3];
285 >  double velA[3], velB[3];
286 >  double pab[3];
287 >  double rab[3];
288 >  int a, b, ax, ay, az, bx, by, bz;
289 >  double rma, rmb;
290 >  double dx, dy, dz;
291 >  double rpab;
292 >  double rabsq, pabsq, rpabsq;
293 >  double diffsq;
294 >  double gab;
295 >  int iteration;
296 >
297 >  for (i = 0; i < nAtoms; i++){
298 >    moving[i] = 0;
299 >    moved[i] = 1;
300 >  }
301 >
302 >  iteration = 0;
303 >  done = 0;
304 >  while (!done && (iteration < 2*maxIteration)){
305 >    done = 1;
306 >    for (i = 0; i < nConstrained; i++){
307 >      a = constrainedA[i];
308 >      b = constrainedB[i];
309 >
310 >      ax = (a * 3) + 0;
311 >      ay = (a * 3) + 1;
312 >      az = (a * 3) + 2;
313 >
314 >      bx = (b * 3) + 0;
315 >      by = (b * 3) + 1;
316 >      bz = (b * 3) + 2;
317 >
318 >      if (moved[a] || moved[b]){
319 >        atoms[a]->getPos(posA);
320 >        atoms[b]->getPos(posB);
321 >
322 >        for (j = 0; j < 3; j++)
323 >          pab[j] = posA[j] - posB[j];
324 >
325 >        //periodic boundary condition
326 >
327 >        info->wrapVector(pab);
328 >
329 >        pabsq = pab[0] * pab[0] + pab[1] * pab[1] + pab[2] * pab[2];
330 >
331 >        rabsq = constrainedDsqr[i];
332 >        diffsq = rabsq - pabsq;
333 >
334 >        // the original rattle code from alan tidesley
335 >        if (fabs(diffsq) > (tol * rabsq * 2)){
336 >          rab[0] = oldPos[ax] - oldPos[bx];
337 >          rab[1] = oldPos[ay] - oldPos[by];
338 >          rab[2] = oldPos[az] - oldPos[bz];
339 >
340 >          info->wrapVector(rab);
341 >          
342 >          rpab = rab[0] * pab[0] + rab[1] * pab[1] + rab[2] * pab[2];
343 >
344 >          rpabsq = rpab * rpab;
345 >
346 >
347 >          if (rpabsq < (rabsq * -diffsq)){
348 > #ifdef IS_MPI
349 >            a = atoms[a]->getGlobalIndex();
350 >            b = atoms[b]->getGlobalIndex();
351 > #endif //is_mpi
352 >            //cerr << "Waring: constraint failure" << endl;
353 >            gab = sqrt(rabsq/pabsq);
354 >            rab[0] = (posA[0] - posB[0])*gab;
355 >            rab[1]= (posA[1] - posB[1])*gab;
356 >            rab[2] = (posA[2] - posB[2])*gab;
357 >            
358 >            info->wrapVector(rab);
359 >            
360 >            rpab = rab[0] * pab[0] + rab[1] * pab[1] + rab[2] * pab[2];
361 >            
362 >          }
363 >
364 >          //rma = 1.0 / atoms[a]->getMass();
365 >          //rmb = 1.0 / atoms[b]->getMass();
366 >          rma = 1.0;
367 >          rmb =1.0;
368 >
369 >          gab = diffsq / (2.0 * (rma + rmb) * rpab);
370 >
371 >          dx = rab[0] * gab;
372 >          dy = rab[1] * gab;
373 >          dz = rab[2] * gab;
374 >
375 >          posA[0] += rma * dx;
376 >          posA[1] += rma * dy;
377 >          posA[2] += rma * dz;
378 >
379 >          atoms[a]->setPos(posA);
380 >
381 >          posB[0] -= rmb * dx;
382 >          posB[1] -= rmb * dy;
383 >          posB[2] -= rmb * dz;
384 >
385 >          atoms[b]->setPos(posB);
386 >
387 >          moving[a] = 1;
388 >          moving[b] = 1;
389 >          done = 0;
390 >        }
391 >      }
392 >    }
393 >
394 >    for (i = 0; i < nAtoms; i++){
395 >      moved[i] = moving[i];
396 >      moving[i] = 0;
397 >    }
398 >
399 >    iteration++;
400 >  }
401 >
402 >  if (!done)
403 >     cerr << "Waring: can not constraint within maxIteration" << endl;
404 > }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines