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