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

Comparing:
trunk/src/minimizers/Minimizer.cpp (property svn:keywords), Revision 258 by tim, Fri Jan 14 01:04:57 2005 UTC vs.
branches/development/src/minimizers/Minimizer.cpp (property svn:keywords), Revision 1627 by gezelter, Tue Sep 13 22:05:04 2011 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines