ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/minimizers/Minimizer.cpp
Revision: 1665
Committed: Tue Nov 22 20:38:56 2011 UTC (13 years, 5 months ago) by gezelter
File size: 18536 byte(s)
Log Message:
updated copyright notices

File Contents

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

Properties

Name Value
svn:executable *
svn:keywords Author Id Revision Date