ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/minimizers/Minimizer.cpp
Revision: 3432
Committed: Mon Jul 14 12:35:58 2008 UTC (16 years, 9 months ago) by gezelter
File size: 18396 byte(s)
Log Message:
Changes for implementing Amber force field:  Added Inversions and
worked on BaseAtomTypes so that they'd function with the fortran side.

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

Properties

Name Value
svn:executable *