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 1056 by tim, Tue Feb 10 21:33:44 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 <  statOut = new StatWriter(info);
8 <  calcDim();
9 < }
10 <
11 < OOPSEMinimizerBase::~OOPSEMinimizerBase(){
12 <  delete tStats;
13 <  delete dumpOut;
14 <  delete statOut;
15 < }
16 <
17 < /**
18 < *
19 < */
20 <
21 <
22 < double OOPSEMinimizerBase::calcGradient(vector<double>& x, vector<double>& grad){
23 <  Atom** atoms;  
24 <  DirectionalAtom* dAtom;
25 <  int index;
26 <  double force[3];
27 <  double dAtomGrad[6];
28 <
29 <  setCoor(x);
30 <  calcForce(1, 1);
31 <  
32 <  atoms = info->atoms;
33 <  index = 0;
34 <
35 <  for(int i = 0; i < nAtoms; i++){
36 <
37 <    if(atoms[i]->isDirectional()){
38 <      dAtom = (DirectionalAtom*) atoms[i];
39 <      dAtom->getGrad(dAtomGrad);
40 <
41 <      //gradient = du/dx = -f
42 <      grad[index++] = -dAtomGrad[0];
43 <      grad[index++] = -dAtomGrad[1];
44 <      grad[index++] = -dAtomGrad[2];
45 <      grad[index++] = -dAtomGrad[3];
46 <      grad[index++] = -dAtomGrad[4];
47 <      grad[index++] = -dAtomGrad[5];
48 <
49 <    }
50 <    else{
51 <      atoms[i]->getFrc(force);
52 <
53 <      grad[index++] = -force[0];
54 <      grad[index++] = -force[1];
55 <      grad[index++] = -force[2];
56 <
57 <    }
58 <    
59 <  }
60 <
61 <  return tStats->getPotential();
62 <  
63 < }
64 <
65 < /**
66 < *
67 < */
68 <
69 < void OOPSEMinimizerBase::setCoor(vector<double>& x){
70 <  Atom** atoms;  
71 <  DirectionalAtom* dAtom;
72 <  int index;
73 <  double position[3];
74 <  double eulerAngle[3];
75 <
76 <  atoms = info->atoms;
77 <  index = 0;
78 <  
79 <  for(int i = 0; i < nAtoms; i++){
80 <    
81 <    position[0] = x[index++];
82 <    position[1] = x[index++];
83 <    position[2] = x[index++];
84 <
85 <    atoms[i]->setPos(position);
86 <
87 <    if (atoms[i]->isDirectional()){
88 <      dAtom = (DirectionalAtom*) atoms[i];
89 <
90 <      eulerAngle[0] = x[index++];
91 <      eulerAngle[1] = x[index++];
92 <      eulerAngle[2] = x[index++];
93 <
94 <       dAtom->setEuler(eulerAngle[0], eulerAngle[1], eulerAngle[2]);
95 <
96 <    }
97 <    
98 <  }
99 <  
100 < }
101 <
102 < /**
103 < *
104 < */
105 < vector<double> OOPSEMinimizerBase::getCoor(){
106 <  Atom** atoms;  
107 <  DirectionalAtom* dAtom;
108 <  int index;
109 <  double position[3];
110 <  double eulerAngle[3];
111 <  vector<double> x;
112 <
113 <  x.resize(getDim());
114 <  atoms = info->atoms;
115 <  index = 0;
116 <  
117 <  for(int i = 0; i < nAtoms; i++){
118 <    atoms[i]->getPos(position);
119 <
120 <    x[index++] = position[0];
121 <    x[index++] = position[1];
122 <    x[index++] = position[2];
123 <
124 <    if (atoms[i]->isDirectional()){
125 <      dAtom = (DirectionalAtom*) atoms[i];
126 <      dAtom->getEulerAngles(eulerAngle);
127 <
128 <      x[index++] = eulerAngle[0];
129 <      x[index++] = eulerAngle[1];
130 <      x[index++] = eulerAngle[2];
131 <      
132 <    }
133 <    
134 <  }
135 <
136 <  return x;
137 <
138 < }
139 <        
140 < void OOPSEMinimizerBase::calcDim(){
141 <  Atom** atoms;  
142 <  DirectionalAtom* dAtom;
143 <
144 <  dim = 0;
145 <
146 <  atoms = info->atoms;
147 <  
148 <  for(int i = 0; i < nAtoms; i++){
149 <    dim += 3;
150 <    if (atoms[i]->isDirectional())
151 <      dim += 3;      
152 <  }
153 <
154 < }
155 <
156 < void OOPSEMinimizerBase::output(vector<double>& x, int iteration){
157 <  setCoor(x);
158 <  calcForce(1, 1);
159 <  dumpOut->writeDump(iteration);
160 <  statOut->writeStat(iteration);
161 < }
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