ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/minimizers/Minimizer.cpp
Revision: 1442
Committed: Mon May 10 17:28:26 2010 UTC (14 years, 11 months ago) by gezelter
Original Path: trunk/src/minimizers/Minimizer.cpp
File size: 18443 byte(s)
Log Message:
Adding property set to svn entries

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

Properties

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