ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/minimizers/Minimizer.cpp
(Generate patch)

Comparing:
trunk/src/minimizers/Minimizer.cpp (file contents), Revision 376 by tim, Thu Feb 24 20:55:07 2005 UTC vs.
branches/development/src/minimizers/Minimizer.cpp (file contents), Revision 1465 by chuckv, Fri Jul 9 23:08:25 2010 UTC

# Line 1 | Line 1
1 < /*
1 > /*
2   * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3   *
4   * The University of Notre Dame grants you ("Licensee") a
# Line 6 | Line 6
6   * redistribute this software in source and binary code form, provided
7   * that the following conditions are met:
8   *
9 < * 1. Acknowledgement of the program authors must be made in any
10 < *    publication of scientific results based in part on use of the
11 < *    program.  An acceptable form of acknowledgement is citation of
12 < *    the article in which the program was described (Matthew
13 < *    A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14 < *    J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15 < *    Parallel Simulation Engine for Molecular Dynamics,"
16 < *    J. Comput. Chem. 26, pp. 252-271 (2005))
17 < *
18 < * 2. Redistributions of source code must retain the above copyright
9 > * 1. Redistributions of source code must retain the above copyright
10   *    notice, this list of conditions and the following disclaimer.
11   *
12 < * 3. Redistributions in binary form must reproduce the above copyright
12 > * 2. Redistributions in binary form must reproduce the above copyright
13   *    notice, this list of conditions and the following disclaimer in the
14   *    documentation and/or other materials provided with the
15   *    distribution.
# Line 37 | Line 28
28   * arising out of the use of or inability to use software, even if the
29   * University of Notre Dame has been advised of the possibility of
30   * such damages.
31 + *
32 + * SUPPORT OPEN SCIENCE!  If you use OpenMD or its source code in your
33 + * research, please cite the appropriate papers when you publish your
34 + * work.  Good starting points are:
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).          
39 + * [4]  Vardeman & Gezelter, in progress (2009).                        
40   */
41  
42   #include <cmath>
# Line 45 | Line 45
45   #include "io/StatWriter.hpp"
46   #include "minimizers/Minimizer.hpp"
47   #include "primitives/Molecule.hpp"
48 < namespace oopse {
49 < double dotProduct(const std::vector<double>& v1, const std::vector<double>& v2) {
48 > namespace OpenMD {
49 >  RealType dotProduct(const std::vector<RealType>& v1, const std::vector<RealType>& v2) {
50      if (v1.size() != v2.size()) {
51  
52      }
53  
54  
55 <    double result = 0.0;    
55 >    RealType result = 0.0;    
56      for (unsigned int i = 0; i < v1.size(); ++i) {
57 <        result += v1[i] * v2[i];
57 >      result += v1[i] * v2[i];
58      }
59  
60      return result;
61 < }
61 >  }
62  
63 < Minimizer::Minimizer(SimInfo* rhs) :
63 >  Minimizer::Minimizer(SimInfo* rhs) :
64      info(rhs), usingShake(false) {
65  
66 <    forceMan = new ForceManager(info);
67 <    paramSet= new MinimizerParameterSet(info),
68 <    calcDim();
69 <    curX = getCoor();
70 <    curG.resize(ndim);
66 >      forceMan = new ForceManager(info);
67 >      paramSet= new MinimizerParameterSet(info), calcDim();
68 >      curX = getCoor();
69 >      curG.resize(ndim);
70  
71 < }
71 >    }
72  
73 < Minimizer::~Minimizer() {
73 >  Minimizer::~Minimizer() {
74      delete forceMan;
75      delete paramSet;
76 < }
76 >  }
77  
78 < void Minimizer::calcEnergyGradient(std::vector<double> &x,
79 <    std::vector<double> &grad, double&energy, int&status) {
78 >  void Minimizer::calcEnergyGradient(std::vector<RealType> &x,
79 >                                     std::vector<RealType> &grad, RealType&energy, int&status) {
80  
81      SimInfo::MoleculeIterator i;
82      Molecule::IntegrableObjectIterator  j;
83      Molecule* mol;
84      StuntDouble* integrableObject;    
85 <    std::vector<double> myGrad;    
85 >    std::vector<RealType> myGrad;    
86      int shakeStatus;
87  
88      status = 1;
# Line 91 | Line 90 | void Minimizer::calcEnergyGradient(std::vector<double>
90      setCoor(x);
91  
92      if (usingShake) {
93 <        shakeStatus = shakeR();
93 >      shakeStatus = shakeR();
94      }
95  
96      energy = calcPotential();
97  
98      if (usingShake) {
99 <        shakeStatus = shakeF();
99 >      shakeStatus = shakeF();
100      }
101  
102      x = getCoor();
# Line 105 | Line 104 | void Minimizer::calcEnergyGradient(std::vector<double>
104      int index = 0;
105  
106      for (mol = info->beginMolecule(i); mol != NULL; mol = info->nextMolecule(i)) {
107 <        for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
108 <               integrableObject = mol->nextIntegrableObject(j)) {
107 >      for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
108 >           integrableObject = mol->nextIntegrableObject(j)) {
109  
110 <            myGrad = integrableObject->getGrad();
111 <            for (unsigned int k = 0; k < myGrad.size(); ++k) {
112 <                //gradient is equal to -f
113 <                grad[index++] = -myGrad[k];
114 <            }
115 <        }            
110 >        myGrad = integrableObject->getGrad();
111 >        for (unsigned int k = 0; k < myGrad.size(); ++k) {
112 >
113 >          grad[index++] = myGrad[k];
114 >        }
115 >      }            
116      }
117  
118 < }
118 >  }
119  
120 < void Minimizer::setCoor(std::vector<double> &x) {
120 >  void Minimizer::setCoor(std::vector<RealType> &x) {
121      Vector3d position;
122      Vector3d eulerAngle;
123      SimInfo::MoleculeIterator i;
# Line 128 | Line 127 | void Minimizer::setCoor(std::vector<double> &x) {
127      int index = 0;
128  
129      for (mol = info->beginMolecule(i); mol != NULL; mol = info->nextMolecule(i)) {
130 <        for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
131 <               integrableObject = mol->nextIntegrableObject(j)) {
130 >      for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
131 >           integrableObject = mol->nextIntegrableObject(j)) {
132  
133 <            position[0] = x[index++];
134 <            position[1] = x[index++];
135 <            position[2] = x[index++];
133 >        position[0] = x[index++];
134 >        position[1] = x[index++];
135 >        position[2] = x[index++];
136  
137 <            integrableObject->setPos(position);
137 >        integrableObject->setPos(position);
138  
139 <            if (integrableObject->isDirectional()) {
140 <                eulerAngle[0] = x[index++];
141 <                eulerAngle[1] = x[index++];
142 <                eulerAngle[2] = x[index++];
139 >        if (integrableObject->isDirectional()) {
140 >          eulerAngle[0] = x[index++];
141 >          eulerAngle[1] = x[index++];
142 >          eulerAngle[2] = x[index++];
143  
144 <                integrableObject->setEuler(eulerAngle);
145 <            }
146 <        }
144 >          integrableObject->setEuler(eulerAngle);
145 >        }
146 >      }
147      }
148      
149 < }
149 >  }
150  
151 < std::vector<double> Minimizer::getCoor() {
151 >  std::vector<RealType> Minimizer::getCoor() {
152      Vector3d position;
153      Vector3d eulerAngle;
154      SimInfo::MoleculeIterator i;
# Line 157 | Line 156 | std::vector<double> Minimizer::getCoor() {
156      Molecule* mol;
157      StuntDouble* integrableObject;    
158      int index = 0;
159 <    std::vector<double> x(getDim());
159 >    std::vector<RealType> x(getDim());
160  
161      for (mol = info->beginMolecule(i); mol != NULL; mol = info->nextMolecule(i)) {
162 <        for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
163 <               integrableObject = mol->nextIntegrableObject(j)) {
162 >      for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
163 >           integrableObject = mol->nextIntegrableObject(j)) {
164                  
165 <            position = integrableObject->getPos();
166 <            x[index++] = position[0];
167 <            x[index++] = position[1];
168 <            x[index++] = position[2];
165 >        position = integrableObject->getPos();
166 >        x[index++] = position[0];
167 >        x[index++] = position[1];
168 >        x[index++] = position[2];
169  
170 <            if (integrableObject->isDirectional()) {
171 <                eulerAngle = integrableObject->getEuler();
172 <                x[index++] = eulerAngle[0];
173 <                x[index++] = eulerAngle[1];
174 <                x[index++] = eulerAngle[2];
175 <            }
176 <        }
170 >        if (integrableObject->isDirectional()) {
171 >          eulerAngle = integrableObject->getEuler();
172 >          x[index++] = eulerAngle[0];
173 >          x[index++] = eulerAngle[1];
174 >          x[index++] = eulerAngle[2];
175 >        }
176 >      }
177      }
178      return x;
179 < }
179 >  }
180  
181  
182 < /*
183 < int Minimizer::shakeR() {
182 >  /*
183 >    int Minimizer::shakeR() {
184      int    i,       j;
185  
186      int    done;
187  
188 <    double posA[3], posB[3];
188 >    RealType posA[3], posB[3];
189  
190 <    double velA[3], velB[3];
190 >    RealType velA[3], velB[3];
191  
192 <    double pab[3];
192 >    RealType pab[3];
193  
194 <    double rab[3];
194 >    RealType rab[3];
195  
196      int    a,       b,
197 <           ax,      ay,
198 <           az,      bx,
199 <           by,      bz;
197 >    ax,      ay,
198 >    az,      bx,
199 >    by,      bz;
200  
201 <    double rma,     rmb;
201 >    RealType rma,     rmb;
202  
203 <    double dx,      dy,
204 <           dz;
203 >    RealType dx,      dy,
204 >    dz;
205  
206 <    double rpab;
206 >    RealType rpab;
207  
208 <    double rabsq,   pabsq,
209 <           rpabsq;
208 >    RealType rabsq,   pabsq,
209 >    rpabsq;
210  
211 <    double diffsq;
211 >    RealType diffsq;
212  
213 <    double gab;
213 >    RealType gab;
214  
215      int    iteration;
216  
217      for(i = 0; i < nAtoms; i++) {
218 <        moving[i] = 0;
218 >    moving[i] = 0;
219  
220 <        moved[i] = 1;
220 >    moved[i] = 1;
221      }
222  
223      iteration = 0;
# Line 226 | Line 225 | int Minimizer::shakeR() {
225      done = 0;
226  
227      while (!done && (iteration < maxIteration)) {
228 <        done = 1;
228 >    done = 1;
229  
230 <        for(i = 0; i < nConstrained; i++) {
231 <            a = constrainedA[i];
230 >    for(i = 0; i < nConstrained; i++) {
231 >    a = constrainedA[i];
232  
233 <            b = constrainedB[i];
233 >    b = constrainedB[i];
234  
235 <            ax = (a * 3) + 0;
235 >    ax = (a * 3) + 0;
236  
237 <            ay = (a * 3) + 1;
237 >    ay = (a * 3) + 1;
238  
239 <            az = (a * 3) + 2;
239 >    az = (a * 3) + 2;
240  
241 <            bx = (b * 3) + 0;
241 >    bx = (b * 3) + 0;
242  
243 <            by = (b * 3) + 1;
243 >    by = (b * 3) + 1;
244  
245 <            bz = (b * 3) + 2;
245 >    bz = (b * 3) + 2;
246  
247 <            if (moved[a] || moved[b]) {
248 <                posA = atoms[a]->getPos();
250 <
251 <                posB = atoms[b]->getPos();
247 >    if (moved[a] || moved[b]) {
248 >    posA = atoms[a]->getPos();
249  
250 <                for(j = 0; j < 3; j++)
254 <            pab[j] = posA[j] - posB[j];
250 >    posB = atoms[b]->getPos();
251  
252 <                //periodic boundary condition
252 >    for(j = 0; j < 3; j++)
253 >    pab[j] = posA[j] - posB[j];
254  
255 <                info->wrapVector(pab);
255 >    //periodic boundary condition
256  
257 <                pabsq = pab[0] * pab[0] + pab[1] * pab[1] + pab[2] * pab[2];
257 >    info->wrapVector(pab);
258  
259 <                rabsq = constrainedDsqr[i];
259 >    pabsq = pab[0] * pab[0] + pab[1] * pab[1] + pab[2] * pab[2];
260  
261 <                diffsq = rabsq - pabsq;
261 >    rabsq = constrainedDsqr[i];
262  
263 <                // the original rattle code from alan tidesley
263 >    diffsq = rabsq - pabsq;
264  
265 <                if (fabs(diffsq) > (tol * rabsq * 2)) {
269 <                    rab[0] = oldPos[ax] - oldPos[bx];
265 >    // the original rattle code from alan tidesley
266  
267 <                    rab[1] = oldPos[ay] - oldPos[by];
267 >    if (fabs(diffsq) > (tol * rabsq * 2)) {
268 >    rab[0] = oldPos[ax] - oldPos[bx];
269  
270 <                    rab[2] = oldPos[az] - oldPos[bz];
270 >    rab[1] = oldPos[ay] - oldPos[by];
271  
272 <                    info->wrapVector(rab);
272 >    rab[2] = oldPos[az] - oldPos[bz];
273  
274 <                    rpab = rab[0] * pab[0] + rab[1] * pab[1] + rab[2] * pab[2];
274 >    info->wrapVector(rab);
275  
276 <                    rpabsq = rpab * rpab;
276 >    rpab = rab[0] * pab[0] + rab[1] * pab[1] + rab[2] * pab[2];
277  
278 <                    if (rpabsq < (rabsq * -diffsq)) {
278 >    rpabsq = rpab * rpab;
279  
280 < #ifdef IS_MPI
280 >    if (rpabsq < (rabsq * -diffsq)) {
281  
282 <                        a = atoms[a]->getGlobalIndex();
282 >    #ifdef IS_MPI
283  
284 <                        b = atoms[b]->getGlobalIndex();
284 >    a = atoms[a]->getGlobalIndex();
285  
286 < #endif //is_mpi
286 >    b = atoms[b]->getGlobalIndex();
287  
288 <                        //std::cerr << "Waring: constraint failure" << std::endl;
288 >    #endif //is_mpi
289  
290 <                        gab = sqrt(rabsq / pabsq);
290 >    //std::cerr << "Waring: constraint failure" << std::endl;
291  
292 <                        rab[0] = (posA[0] - posB[0])
296 <                        * gab;
292 >    gab = sqrt(rabsq / pabsq);
293  
294 <                        rab[1] = (posA[1] - posB[1])
295 <                        * gab;
294 >    rab[0] = (posA[0] - posB[0])
295 >    * gab;
296  
297 <                        rab[2] = (posA[2] - posB[2])
298 <                        * gab;
297 >    rab[1] = (posA[1] - posB[1])
298 >    * gab;
299  
300 <                        info->wrapVector(rab);
300 >    rab[2] = (posA[2] - posB[2])
301 >    * gab;
302  
303 <                        rpab =
307 <                            rab[0] * pab[0] + rab[1] * pab[1] + rab[2] * pab[2];
308 <                    }
303 >    info->wrapVector(rab);
304  
305 <                    //rma = 1.0 / atoms[a]->getMass();
305 >    rpab =
306 >    rab[0] * pab[0] + rab[1] * pab[1] + rab[2] * pab[2];
307 >    }
308  
309 <                    //rmb = 1.0 / atoms[b]->getMass();
309 >    //rma = 1.0 / atoms[a]->getMass();
310  
311 <                    rma = 1.0;
311 >    //rmb = 1.0 / atoms[b]->getMass();
312  
313 <                    rmb = 1.0;
313 >    rma = 1.0;
314  
315 <                    gab = diffsq / (2.0 * (rma + rmb) * rpab);
315 >    rmb = 1.0;
316  
317 <                    dx = rab[0]*
321 <                    gab;
317 >    gab = diffsq / (2.0 * (rma + rmb) * rpab);
318  
319 <                    dy = rab[1]*
320 <                    gab;
319 >    dx = rab[0]*
320 >    gab;
321  
322 <                    dz = rab[2]*
323 <                    gab;
322 >    dy = rab[1]*
323 >    gab;
324  
325 <                    posA[0] += rma *dx;
325 >    dz = rab[2]*
326 >    gab;
327  
328 <                    posA[1] += rma *dy;
328 >    posA[0] += rma *dx;
329  
330 <                    posA[2] += rma *dz;
330 >    posA[1] += rma *dy;
331  
332 <                    atoms[a]->setPos(posA);
332 >    posA[2] += rma *dz;
333  
334 <                    posB[0] -= rmb *dx;
334 >    atoms[a]->setPos(posA);
335  
336 <                    posB[1] -= rmb *dy;
336 >    posB[0] -= rmb *dx;
337  
338 <                    posB[2] -= rmb *dz;
338 >    posB[1] -= rmb *dy;
339  
340 <                    atoms[b]->setPos(posB);
340 >    posB[2] -= rmb *dz;
341  
342 <                    moving[a] = 1;
342 >    atoms[b]->setPos(posB);
343  
344 <                    moving[b] = 1;
344 >    moving[a] = 1;
345  
346 <                    done = 0;
350 <                }
351 <            }
352 <        }
346 >    moving[b] = 1;
347  
348 <        for(i = 0; i < nAtoms; i++) {
349 <            moved[i] = moving[i];
348 >    done = 0;
349 >    }
350 >    }
351 >    }
352  
353 <            moving[i] = 0;
354 <        }
353 >    for(i = 0; i < nAtoms; i++) {
354 >    moved[i] = moving[i];
355  
356 <        iteration++;
356 >    moving[i] = 0;
357      }
358  
359 +    iteration++;
360 +    }
361 +
362      if (!done) {
363 <        std::cerr << "Waring: can not constraint within maxIteration"
364 <            << std::endl;
363 >    std::cerr << "Waring: can not constraint within maxIteration"
364 >    << std::endl;
365  
366 <        return -1;
366 >    return -1;
367      } else
368 <        return 1;
369 < }
368 >    return 1;
369 >    }
370  
371 < //remove constraint force along the bond direction
371 >    //remove constraint force along the bond direction
372  
373  
374 < int Minimizer::shakeF() {
374 >    int Minimizer::shakeF() {
375      int    i,       j;
376  
377      int    done;
378  
379 <    double posA[3], posB[3];
379 >    RealType posA[3], posB[3];
380  
381 <    double frcA[3], frcB[3];
381 >    RealType frcA[3], frcB[3];
382  
383 <    double rab[3],  fpab[3];
383 >    RealType rab[3],  fpab[3];
384  
385      int    a,       b,
386 <           ax,      ay,
387 <           az,      bx,
388 <           by,      bz;
386 >    ax,      ay,
387 >    az,      bx,
388 >    by,      bz;
389  
390 <    double rma,     rmb;
390 >    RealType rma,     rmb;
391  
392 <    double rvab;
392 >    RealType rvab;
393  
394 <    double gab;
394 >    RealType gab;
395  
396 <    double rabsq;
396 >    RealType rabsq;
397  
398 <    double rfab;
398 >    RealType rfab;
399  
400      int    iteration;
401  
402      for(i = 0; i < nAtoms; i++) {
403 <        moving[i] = 0;
403 >    moving[i] = 0;
404  
405 <        moved[i] = 1;
405 >    moved[i] = 1;
406      }
407  
408      done = 0;
# Line 411 | Line 410 | int Minimizer::shakeF() {
410      iteration = 0;
411  
412      while (!done && (iteration < maxIteration)) {
413 <        done = 1;
413 >    done = 1;
414  
415 <        for(i = 0; i < nConstrained; i++) {
416 <            a = constrainedA[i];
415 >    for(i = 0; i < nConstrained; i++) {
416 >    a = constrainedA[i];
417  
418 <            b = constrainedB[i];
418 >    b = constrainedB[i];
419  
420 <            ax = (a * 3) + 0;
420 >    ax = (a * 3) + 0;
421  
422 <            ay = (a * 3) + 1;
422 >    ay = (a * 3) + 1;
423  
424 <            az = (a * 3) + 2;
424 >    az = (a * 3) + 2;
425  
426 <            bx = (b * 3) + 0;
426 >    bx = (b * 3) + 0;
427  
428 <            by = (b * 3) + 1;
428 >    by = (b * 3) + 1;
429  
430 <            bz = (b * 3) + 2;
430 >    bz = (b * 3) + 2;
431  
432 <            if (moved[a] || moved[b]) {
433 <                posA = atoms[a]->getPos();
432 >    if (moved[a] || moved[b]) {
433 >    posA = atoms[a]->getPos();
434  
435 <                posB = atoms[b]->getPos();
435 >    posB = atoms[b]->getPos();
436  
437 <                for(j = 0; j < 3; j++)
438 <            rab[j] = posA[j] - posB[j];
437 >    for(j = 0; j < 3; j++)
438 >    rab[j] = posA[j] - posB[j];
439  
440 <                info->wrapVector(rab);
440 >    info->wrapVector(rab);
441  
442 <                atoms[a]->getFrc(frcA);
442 >    atoms[a]->getFrc(frcA);
443  
444 <                atoms[b]->getFrc(frcB);
444 >    atoms[b]->getFrc(frcB);
445  
446 <                //rma = 1.0 / atoms[a]->getMass();
446 >    //rma = 1.0 / atoms[a]->getMass();
447  
448 <                //rmb = 1.0 / atoms[b]->getMass();
448 >    //rmb = 1.0 / atoms[b]->getMass();
449  
450 <                rma = 1.0;
450 >    rma = 1.0;
451  
452 <                rmb = 1.0;
452 >    rmb = 1.0;
453  
454 <                fpab[0] = frcA[0] * rma - frcB[0] * rmb;
454 >    fpab[0] = frcA[0] * rma - frcB[0] * rmb;
455  
456 <                fpab[1] = frcA[1] * rma - frcB[1] * rmb;
456 >    fpab[1] = frcA[1] * rma - frcB[1] * rmb;
457  
458 <                fpab[2] = frcA[2] * rma - frcB[2] * rmb;
458 >    fpab[2] = frcA[2] * rma - frcB[2] * rmb;
459  
460 <                gab = fpab[0] * fpab[0] + fpab[1] * fpab[1] + fpab[2] * fpab[2];
460 >    gab = fpab[0] * fpab[0] + fpab[1] * fpab[1] + fpab[2] * fpab[2];
461  
462 <                if (gab < 1.0)
463 <                    gab = 1.0;
462 >    if (gab < 1.0)
463 >    gab = 1.0;
464  
465 <                rabsq = rab[0] * rab[0] + rab[1] * rab[1] + rab[2] * rab[2];
465 >    rabsq = rab[0] * rab[0] + rab[1] * rab[1] + rab[2] * rab[2];
466  
467 <                rfab = rab[0] * fpab[0] + rab[1] * fpab[1] + rab[2] * fpab[2];
467 >    rfab = rab[0] * fpab[0] + rab[1] * fpab[1] + rab[2] * fpab[2];
468  
469 <                if (fabs(rfab) > sqrt(rabsq*gab) * 0.00001) {
470 <                    gab = -rfab / (rabsq * (rma + rmb));
469 >    if (fabs(rfab) > sqrt(rabsq*gab) * 0.00001) {
470 >    gab = -rfab / (rabsq * (rma + rmb));
471  
472 <                    frcA[0] = rab[0]*
473 <                    gab;
472 >    frcA[0] = rab[0]*
473 >    gab;
474  
475 <                    frcA[1] = rab[1]*
476 <                    gab;
475 >    frcA[1] = rab[1]*
476 >    gab;
477  
478 <                    frcA[2] = rab[2]*
479 <                    gab;
478 >    frcA[2] = rab[2]*
479 >    gab;
480  
481 <                    atoms[a]->addFrc(frcA);
481 >    atoms[a]->addFrc(frcA);
482  
483 <                    frcB[0] = -rab[0]*gab;
483 >    frcB[0] = -rab[0]*gab;
484  
485 <                    frcB[1] = -rab[1]*gab;
485 >    frcB[1] = -rab[1]*gab;
486  
487 <                    frcB[2] = -rab[2]*gab;
487 >    frcB[2] = -rab[2]*gab;
488  
489 <                    atoms[b]->addFrc(frcB);
489 >    atoms[b]->addFrc(frcB);
490  
491 <                    moving[a] = 1;
491 >    moving[a] = 1;
492  
493 <                    moving[b] = 1;
493 >    moving[b] = 1;
494  
495 <                    done = 0;
496 <                }
497 <            }
498 <        }
495 >    done = 0;
496 >    }
497 >    }
498 >    }
499  
500 <        for(i = 0; i < nAtoms; i++) {
501 <            moved[i] = moving[i];
500 >    for(i = 0; i < nAtoms; i++) {
501 >    moved[i] = moving[i];
502  
503 <            moving[i] = 0;
504 <        }
503 >    moving[i] = 0;
504 >    }
505  
506 <        iteration++;
506 >    iteration++;
507      }
508  
509      if (!done) {
510 <        std::cerr << "Waring: can not constraint within maxIteration"
511 <            << std::endl;
510 >    std::cerr << "Waring: can not constraint within maxIteration"
511 >    << std::endl;
512  
513 <        return -1;
513 >    return -1;
514      } else
515 <        return 1;
516 < }
515 >    return 1;
516 >    }
517  
518 < */
518 >  */
519      
520 < //calculate the value of object function
520 >  //calculate the value of object function
521  
522 < void Minimizer::calcF() {
522 >  void Minimizer::calcF() {
523      calcEnergyGradient(curX, curG, curF, egEvalStatus);
524 < }
524 >  }
525  
526 < void Minimizer::calcF(std::vector < double > &x, double&f, int&status) {
527 <    std::vector < double > tempG;
526 >  void Minimizer::calcF(std::vector < RealType > &x, RealType&f, int&status) {
527 >    std::vector < RealType > tempG;
528  
529      tempG.resize(x.size());
530  
531      calcEnergyGradient(x, tempG, f, status);
532 < }
532 >  }
533  
534 < //calculate the gradient
534 >  //calculate the gradient
535  
536 < void Minimizer::calcG() {
537 <    calcEnergyGradient(curX, curG, curF, egEvalStatus);
538 < }
536 >  void Minimizer::calcG() {
537 >    calcEnergyGradient(curX, curG, curF, egEvalStatus);
538 >  }
539  
540 < void Minimizer::calcG(std::vector<double>& x, std::vector<double>& g, double&f, int&status) {
540 >  void Minimizer::calcG(std::vector<RealType>& x, std::vector<RealType>& g, RealType&f, int&status) {
541      calcEnergyGradient(x, g, f, status);
542 < }
542 >  }
543  
544 < void Minimizer::calcDim() {
544 >  void Minimizer::calcDim() {
545  
546      SimInfo::MoleculeIterator i;
547      Molecule::IntegrableObjectIterator  j;
# Line 551 | Line 550 | void Minimizer::calcDim() {
550      ndim = 0;
551  
552      for (mol = info->beginMolecule(i); mol != NULL; mol = info->nextMolecule(i)) {
553 <        for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
554 <               integrableObject = mol->nextIntegrableObject(j)) {
553 >      for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
554 >           integrableObject = mol->nextIntegrableObject(j)) {
555  
556 <            ndim += 3;
556 >        ndim += 3;
557  
558 <            if (integrableObject->isDirectional()) {
559 <                ndim += 3;
560 <            }
561 <        }
558 >        if (integrableObject->isDirectional()) {
559 >          ndim += 3;
560 >        }
561 >      }
562  
563      }
564 < }
564 >  }
565  
566 < void Minimizer::setX(std::vector < double > &x) {
566 >  void Minimizer::setX(std::vector < RealType > &x) {
567      if (x.size() != ndim) {
568 <        sprintf(painCave.errMsg, "Minimizer Error: dimesion of x and curX does not match\n");
569 <        painCave.isFatal = 1;
570 <        simError();
568 >      sprintf(painCave.errMsg, "Minimizer Error: dimesion of x and curX does not match\n");
569 >      painCave.isFatal = 1;
570 >      simError();
571      }
572  
573      curX = x;
574 < }
574 >  }
575  
576 < void Minimizer::setG(std::vector < double > &g) {
576 >  void Minimizer::setG(std::vector < RealType > &g) {
577      if (g.size() != ndim) {
578 <        sprintf(painCave.errMsg, "Minimizer Error: dimesion of g and curG does not match\n");
579 <        painCave.isFatal = 1;
580 <        simError();
578 >      sprintf(painCave.errMsg, "Minimizer Error: dimesion of g and curG does not match\n");
579 >      painCave.isFatal = 1;
580 >      simError();
581      }
582  
583      curG = g;
584 < }
584 >  }
585  
586  
587 < /**
587 >  /**
588  
589 < * In thoery, we need to find the minimum along the search direction
590 < * However, function evaluation is too expensive.
591 < * At the very begining of the problem, we check the search direction and make sure
592 < * it is a descent direction
593 < * we will compare the energy of two end points,
594 < * if the right end point has lower energy, we just take it
595 < * @todo optimize this line search algorithm
596 < */
589 >  * In thoery, we need to find the minimum along the search direction
590 >  * However, function evaluation is too expensive.
591 >  * At the very begining of the problem, we check the search direction and make sure
592 >  * it is a descent direction
593 >  * we will compare the energy of two end points,
594 >  * if the right end point has lower energy, we just take it
595 >  * @todo optimize this line search algorithm
596 >  */
597  
598 < int Minimizer::doLineSearch(std::vector<double> &direction,
599 <                                 double stepSize) {
598 >  int Minimizer::doLineSearch(std::vector<RealType> &direction,
599 >                              RealType stepSize) {
600  
601 <    std::vector<double> xa;
602 <    std::vector<double> xb;
603 <    std::vector<double> xc;
604 <    std::vector<double> ga;
605 <    std::vector<double> gb;
606 <    std::vector<double> gc;
607 <    double fa;
608 <    double fb;
609 <    double fc;
610 <    double a;
611 <    double b;
612 <    double c;
601 >    std::vector<RealType> xa;
602 >    std::vector<RealType> xb;
603 >    std::vector<RealType> xc;
604 >    std::vector<RealType> ga;
605 >    std::vector<RealType> gb;
606 >    std::vector<RealType> gc;
607 >    RealType fa;
608 >    RealType fb;
609 >    RealType fc;
610 >    RealType a;
611 >    RealType b;
612 >    RealType c;
613      int    status;
614 <    double initSlope;
615 <    double slopeA;
616 <    double slopeB;
617 <    double slopeC;
614 >    RealType initSlope;
615 >    RealType slopeA;
616 >    RealType slopeB;
617 >    RealType slopeC;
618      bool   foundLower;
619      int    iter;
620      int    maxLSIter;
621 <    double mu;
622 <    double eta;
623 <    double ftol;
624 <    double lsTol;
621 >    RealType mu;
622 >    RealType eta;
623 >    RealType ftol;
624 >    RealType lsTol;
625  
626      xa.resize(ndim);
627      xb.resize(ndim);
# Line 650 | Line 649 | int Minimizer::doLineSearch(std::vector<double> &direc
649      slopeA = 0;
650  
651      for(size_t i = 0; i < ndim; i++) {
652 <        slopeA += curG[i] * direction[i];
652 >      slopeA += curG[i] * direction[i];
653      }
654      
655      initSlope = slopeA;
# Line 659 | Line 658 | int Minimizer::doLineSearch(std::vector<double> &direc
658  
659      if (slopeA > 0) {
660  
661 <        for(size_t i = 0; i < ndim; i++) {
662 <            direction[i] = -curG[i];
663 <        }
661 >      for(size_t i = 0; i < ndim; i++) {
662 >        direction[i] = -curG[i];
663 >      }
664          
665 <        for(size_t i = 0; i < ndim; i++) {
666 <            slopeA += curG[i] * direction[i];
667 <        }
665 >      for(size_t i = 0; i < ndim; i++) {
666 >        slopeA += curG[i] * direction[i];
667 >      }
668          
669 <        initSlope = slopeA;
669 >      initSlope = slopeA;
670      }
671  
672      // Take a trial step
673  
674      for(size_t i = 0; i < ndim; i++) {
675 <        xc[i] = curX[i] + direction[i]* c;
675 >      xc[i] = curX[i] + direction[i]* c;
676      }
677      
678      calcG(xc, gc, fc, status);
679  
680      if (status < 0) {
681 <        if (bVerbose)
682 <            std::cerr << "Function Evaluation Error" << std::endl;
681 >      if (bVerbose)
682 >        std::cerr << "Function Evaluation Error" << std::endl;
683      }
684  
685      //calculate the derivative at c
# Line 688 | Line 687 | int Minimizer::doLineSearch(std::vector<double> &direc
687      slopeC = 0;
688  
689      for(size_t i = 0; i < ndim; i++) {
690 <        slopeC += gc[i] * direction[i];
690 >      slopeC += gc[i] * direction[i];
691      }
692      // found a lower point
693  
694      if (fc < fa) {
695 <        curX = xc;
695 >      curX = xc;
696  
697 <        curG = gc;
697 >      curG = gc;
698  
699 <        curF = fc;
699 >      curF = fc;
700  
701 <        return LS_SUCCEED;
701 >      return LS_SUCCEED;
702      } else {
703 <        if (slopeC > 0)
704 <            stepSize *= 0.618034;
703 >      if (slopeC > 0)
704 >        stepSize *= 0.618034;
705      }
706  
707      maxLSIter = paramSet->getLineSearchMaxIteration();
# Line 711 | Line 710 | int Minimizer::doLineSearch(std::vector<double> &direc
710  
711      do {
712  
713 <        // Select a new trial point.
713 >      // Select a new trial point.
714  
715 <        // If the derivatives at points a & c have different sign we use cubic interpolate    
715 >      // If the derivatives at points a & c have different sign we use cubic interpolate    
716  
717 <        //if (slopeC > 0){    
717 >      //if (slopeC > 0){    
718  
719 <        eta = 3 * (fa - fc) / (c - a) + slopeA + slopeC;
719 >      eta = 3 * (fa - fc) / (c - a) + slopeA + slopeC;
720  
721 <        mu = sqrt(eta * eta - slopeA * slopeC);
721 >      mu = sqrt(eta * eta - slopeA * slopeC);
722  
723 <        b = a + (c - a)
724 <                * (1 - (slopeC + mu - eta) / (slopeC - slopeA + 2 * mu));
723 >      b = a + (c - a)
724 >        * (1 - (slopeC + mu - eta) / (slopeC - slopeA + 2 * mu));
725  
726 <        if (b < lsTol) {
727 <            break;
728 <        }
726 >      if (b < lsTol) {
727 >        break;
728 >      }
729  
730 <        //}
730 >      //}
731  
732 <        // Take a trial step to this new point - new coords in xb
732 >      // Take a trial step to this new point - new coords in xb
733  
734 <        for(size_t i = 0; i < ndim; i++) {
735 <            xb[i] = curX[i] + direction[i]* b;
736 <        }
734 >      for(size_t i = 0; i < ndim; i++) {
735 >        xb[i] = curX[i] + direction[i]* b;
736 >      }
737          
738 <        //function evaluation
738 >      //function evaluation
739  
740 <        calcG(xb, gb, fb, status);
740 >      calcG(xb, gb, fb, status);
741  
742 <        if (status < 0) {
743 <            if (bVerbose)
744 <                std::cerr << "Function Evaluation Error" << std::endl;
745 <        }
742 >      if (status < 0) {
743 >        if (bVerbose)
744 >          std::cerr << "Function Evaluation Error" << std::endl;
745 >      }
746  
747 <        //calculate the derivative at c
747 >      //calculate the derivative at c
748  
749 <        slopeB = 0;
749 >      slopeB = 0;
750  
751 <        for(size_t i = 0; i < ndim; i++) {
752 <            slopeB += gb[i] * direction[i];
753 <        }
751 >      for(size_t i = 0; i < ndim; i++) {
752 >        slopeB += gb[i] * direction[i];
753 >      }
754          
755 <        //Amijo Rule to stop the line search
755 >      //Amijo Rule to stop the line search
756  
757 <        if (fb <= curF +  initSlope * ftol * b) {
758 <            curF = fb;
757 >      if (fb <= curF +  initSlope * ftol * b) {
758 >        curF = fb;
759  
760 <            curX = xb;
760 >        curX = xb;
761  
762 <            curG = gb;
762 >        curG = gb;
763  
764 <            return LS_SUCCEED;
765 <        }
767 <
768 <        if (slopeB < 0 && fb < fa) {
764 >        return LS_SUCCEED;
765 >      }
766  
767 <            //replace a by b
767 >      if (slopeB < 0 && fb < fa) {
768  
769 <            fa = fb;
769 >        //replace a by b
770  
771 <            a = b;
771 >        fa = fb;
772  
773 <            slopeA = slopeB;
773 >        a = b;
774  
775 <            // swap coord  a/b
775 >        slopeA = slopeB;
776  
777 <            std::swap(xa, xb);
777 >        // swap coord  a/b
778  
779 <            std::swap(ga, gb);
783 <        } else {
779 >        std::swap(xa, xb);
780  
781 <            //replace c by b
781 >        std::swap(ga, gb);
782 >      } else {
783  
784 <            fc = fb;
784 >        //replace c by b
785  
786 <            c = b;
786 >        fc = fb;
787  
788 <            slopeC = slopeB;
788 >        c = b;
789  
790 <            // swap coord  b/c
790 >        slopeC = slopeB;
791  
792 <            std::swap(gb, gc);
792 >        // swap coord  b/c
793  
794 <            std::swap(xb, xc);
798 <        }
794 >        std::swap(gb, gc);
795  
796 <        iter++;
796 >        std::swap(xb, xc);
797 >      }
798 >
799 >      iter++;
800      } while ((fb > fa || fb > fc) && (iter < maxLSIter));
801  
802      if (fb < curF || iter >= maxLSIter) {
803  
804 <        //could not find a lower value, we might just go uphill.      
804 >      //could not find a lower value, we might just go uphill.      
805  
806 <        return LS_ERROR;
806 >      return LS_ERROR;
807      }
808  
809      //select the end point
810  
811      if (fa <= fc) {
812 <        curX = xa;
812 >      curX = xa;
813  
814 <        curG = ga;
814 >      curG = ga;
815  
816 <        curF = fa;
816 >      curF = fa;
817      } else {
818 <        curX = xc;
818 >      curX = xc;
819  
820 <        curG = gc;
820 >      curG = gc;
821  
822 <        curF = fc;
822 >      curF = fc;
823      }
824  
825      return LS_SUCCEED;
826 < }
826 >  }
827  
828 < void Minimizer::minimize() {
828 >  void Minimizer::minimize() {
829      int convgStatus;
830      int stepStatus;
831      int maxIter;
832 <    int writeFrq;
832 >    int writeFreq;
833      int nextWriteIter;
834      Snapshot* curSnapshot =info->getSnapshotManager()->getCurrentSnapshot();
835      DumpWriter dumpWriter(info);    
# Line 841 | Line 840 | void Minimizer::minimize() {
840  
841      init();
842  
843 <    writeFrq = paramSet->getWriteFrq();
843 >    writeFreq = paramSet->getWriteFreq();
844  
845 <    nextWriteIter = writeFrq;
845 >    nextWriteIter = writeFreq;
846  
847      maxIter = paramSet->getMaxIteration();
848  
849      for(curIter = 1; curIter <= maxIter; curIter++) {
850 <        stepStatus = step();
850 >      stepStatus = step();
851  
852 <        //if (usingShake)
853 <        //    preMove();
852 >      //if (usingShake)
853 >      //    preMove();
854  
855 <        if (stepStatus < 0) {
856 <            saveResult();
855 >      if (stepStatus < 0) {
856 >        saveResult();
857  
858 <            minStatus = MIN_LSERROR;
858 >        minStatus = MIN_LSERROR;
859  
860 <            std::cerr
861 <                << "Minimizer Error: line search error, please try a small stepsize"
862 <                << std::endl;
860 >        std::cerr
861 >          << "Minimizer Error: line search error, please try a small stepsize"
862 >          << std::endl;
863  
864 <            return;
865 <        }
864 >        return;
865 >      }
866  
867 <        //save snapshot
868 <        info->getSnapshotManager()->advance();
869 <        //increase time
870 <        curSnapshot->increaseTime(1);    
867 >      //save snapshot
868 >      info->getSnapshotManager()->advance();
869 >      //increase time
870 >      curSnapshot->increaseTime(1);    
871          
872 <        if (curIter == nextWriteIter) {
873 <            nextWriteIter += writeFrq;
874 <            calcF();
875 <            dumpWriter.writeDump();
876 <            statWriter.writeStat(curSnapshot->statData);
877 <        }
872 >      if (curIter == nextWriteIter) {
873 >        nextWriteIter += writeFreq;
874 >        calcF();
875 >        dumpWriter.writeDumpAndEor();
876 >        statWriter.writeStat(curSnapshot->statData);
877 >      }
878  
879 <        convgStatus = checkConvg();
879 >      convgStatus = checkConvg();
880  
881 <        if (convgStatus > 0) {
882 <            saveResult();
881 >      if (convgStatus > 0) {
882 >        saveResult();
883  
884 <            minStatus = MIN_CONVERGE;
884 >        minStatus = MIN_CONVERGE;
885  
886 <            return;
887 <        }
886 >        return;
887 >      }
888  
889 <        prepareStep();
889 >      prepareStep();
890      }
891  
892      if (bVerbose) {
893 <        std::cout << "Minimizer Warning: " << minimizerName
894 <            << " algorithm did not converge within " << maxIter << " iteration"
895 <            << std::endl;
893 >      std::cout << "Minimizer Warning: " << minimizerName
894 >                << " algorithm did not converge within " << maxIter << " iteration"
895 >                << std::endl;
896      }
897  
898      minStatus = MIN_MAXITER;
899  
900      saveResult();
901 < }
901 >  }
902  
903  
904 < double Minimizer::calcPotential() {
905 <    forceMan->calcForces(true, false);
904 >  RealType Minimizer::calcPotential() {
905 >    forceMan->calcForces();
906  
907      Snapshot* curSnapshot = info->getSnapshotManager()->getCurrentSnapshot();
908 <    double potential_local = curSnapshot->statData[Stats::LONG_RANGE_POTENTIAL] +
909 <                                             curSnapshot->statData[Stats::SHORT_RANGE_POTENTIAL] ;    
910 <    double potential;
908 >    RealType potential_local = curSnapshot->statData[Stats::LONG_RANGE_POTENTIAL] +
909 >      curSnapshot->statData[Stats::SHORT_RANGE_POTENTIAL] ;    
910 >    RealType potential;
911  
912   #ifdef IS_MPI
913 <    MPI_Allreduce(&potential_local, &potential, 1, MPI_DOUBLE, MPI_SUM,
913 >    MPI_Allreduce(&potential_local, &potential, 1, MPI_REALTYPE, MPI_SUM,
914                    MPI_COMM_WORLD);
915   #else
916      potential = potential_local;
# Line 920 | Line 919 | double Minimizer::calcPotential() {
919      //save total potential
920      curSnapshot->statData[Stats::POTENTIAL_ENERGY] = potential;
921      return potential;
922 < }
922 >  }
923  
924   }

Comparing:
trunk/src/minimizers/Minimizer.cpp (property svn:keywords), Revision 376 by tim, Thu Feb 24 20:55:07 2005 UTC vs.
branches/development/src/minimizers/Minimizer.cpp (property svn:keywords), Revision 1465 by chuckv, Fri Jul 9 23:08:25 2010 UTC

# Line 0 | Line 1
1 + Author Id Revision Date

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines