ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.0/src/minimizers/Minimizer.cpp
Revision: 2204
Committed: Fri Apr 15 22:04:00 2005 UTC (19 years, 2 months ago) by gezelter
File size: 18294 byte(s)
Log Message:
xemacs has been drafted to perform our indentation services

File Contents

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

Properties

Name Value
svn:executable *