Revisão | 486d6bbdd08885c502fe67bdbfa2f6a071a5f3e5 (tree) |
---|---|
Hora | 2012-12-05 10:57:29 |
Autor | Katsuhiko Nishimra <ktns.87@gmai...> |
Commiter | Katsuhiko Nishimra |
Push back the oldest error vector after recalculating GDIIS step without it. #28915
git-svn-id: https://svn.sourceforge.jp/svnroot/molds/branches/gdiis@1174 1136aad2-a195-0410-b898-f5ea1d11b9d8
@@ -50,6 +50,7 @@ GDIIS::GDIIS(int sizeErrorVector): | ||
50 | 50 | messageTakingGDIISStep("Taking GDIIS step.\n"), |
51 | 51 | messageSingularGDIISMatrix("Error while solving GDIIS equation. Discarding current data.\n"), |
52 | 52 | messageOnlyOneErrorVector("There is only one error vector.\n"), |
53 | + messageRecalcGDIISStep("Recalculate GDIIS step without the oldest error vector.\n"), | |
53 | 54 | formatTooSmallLagrangeMultiplier("GDIIS: Lagrange Multiplier is too small. (%e)\n"), |
54 | 55 | formatTooLargeGDIISStep("GDIIS: GDIIS step is too large. (gdiis:%e, reference:%e)\n"), |
55 | 56 | formatWrongDirection("GDIIS: GDIIS step direction is too far from reference step. (cosine: %+f)\n") |
@@ -131,6 +132,7 @@ void GDIIS::CalcGDIIS(double* vectorError, | ||
131 | 132 | |
132 | 133 | // If only one error vector is given, following routine is meaningless. |
133 | 134 | if(numErrors <= 1){ |
135 | + this->OutputLog(messageOnlyOneErrorVector); | |
134 | 136 | throw GDIISException(this->messageOnlyOneErrorVector); |
135 | 137 | } |
136 | 138 |
@@ -158,8 +160,7 @@ void GDIIS::CalcGDIIS(double* vectorError, | ||
158 | 160 | this->OutputLog((this->formatTooSmallLagrangeMultiplier % -vectorCoefs[numErrors]).str()); |
159 | 161 | MallocerFreer::GetInstance()->Free(&vectorCoefs, numErrors+1); |
160 | 162 | // Recalculate GDIIS step without the oldest data. |
161 | - this->DiscardOldest(); | |
162 | - return CalcGDIIS(vectorError,vectorPosition,vectorRefStep); | |
163 | + return this->RecalcGDIIS(vectorError,vectorPosition,vectorRefStep); | |
163 | 164 | } |
164 | 165 | |
165 | 166 | // Interpolate error vectors and positions |
@@ -193,8 +194,7 @@ void GDIIS::CalcGDIIS(double* vectorError, | ||
193 | 194 | this->OutputLog((this->formatTooLargeGDIISStep % sqrt(normSquaregdiis) % sqrt(normSquareref)).str()); |
194 | 195 | MallocerFreer::GetInstance()->Free(&vectorCoefs, numErrors+1); |
195 | 196 | // and recalculate GDIIS step without the oldest data |
196 | - this->DiscardOldest(); | |
197 | - return CalcGDIIS(vectorError,vectorPosition,vectorRefStep); | |
197 | + return this->RecalcGDIIS(vectorError,vectorPosition,vectorRefStep); | |
198 | 198 | } |
199 | 199 | |
200 | 200 | // If the calculated cos(theta) on Eq. 8 of [FS_2002] is below the minimum tolerant value |
@@ -207,8 +207,7 @@ void GDIIS::CalcGDIIS(double* vectorError, | ||
207 | 207 | this->OutputLog((formatWrongDirection % cosine).str()); |
208 | 208 | MallocerFreer::GetInstance()->Free(&vectorCoefs, numErrors+1); |
209 | 209 | // and recalculate GDIIS step without the oldest data |
210 | - this->DiscardOldest(); | |
211 | - return CalcGDIIS(vectorError,vectorPosition,vectorRefStep); | |
210 | + return this->RecalcGDIIS(vectorError,vectorPosition,vectorRefStep); | |
212 | 211 | } |
213 | 212 | } |
214 | 213 | catch(GDIISException ex){ |
@@ -223,6 +222,30 @@ void GDIIS::CalcGDIIS(double* vectorError, | ||
223 | 222 | this->OutputLog(messageTakingGDIISStep); |
224 | 223 | } |
225 | 224 | |
225 | +void GDIIS::RecalcGDIIS(double* vectorError, | |
226 | + double* vectorPosition, | |
227 | + double const* vectorRefStep) throw(GDIISException, MolDS_base::MolDSException){ | |
228 | + double *vectorErrorOldest = NULL; | |
229 | + double *vectorPositionOldest = NULL; | |
230 | + | |
231 | + this->PopOldest(&vectorErrorOldest, &vectorPositionOldest); | |
232 | + | |
233 | + this->OutputLog(messageRecalcGDIISStep); | |
234 | + | |
235 | + try{ | |
236 | + this->CalcGDIIS(vectorError, vectorPosition, vectorRefStep); | |
237 | + } | |
238 | + catch(GDIISException ex){ | |
239 | + this->PushOldest(vectorErrorOldest, vectorPositionOldest); | |
240 | + throw ex; | |
241 | + } | |
242 | + catch(MolDSException ex){ | |
243 | + MallocerFreer::GetInstance()->Free(&vectorErrorOldest, this->sizeErrorVector); | |
244 | + MallocerFreer::GetInstance()->Free(&vectorPositionOldest, this->sizeErrorVector); | |
245 | + throw ex; | |
246 | + } | |
247 | +} | |
248 | + | |
226 | 249 | void GDIIS::DoGDIIS(double *vectorError, Molecule& molecule, double const* vectorRefStep) throw(GDIISException, MolDS_base::MolDSException){ |
227 | 250 | double** matrixPosition = NULL; |
228 | 251 | try{ |
@@ -53,6 +53,9 @@ private: | ||
53 | 53 | void CalcGDIIS(double* vectorError, |
54 | 54 | double* vectorPosition, |
55 | 55 | double const* vectorRefStep) throw(GDIISException, MolDS_base::MolDSException); |
56 | + void RecalcGDIIS(double* vectorError, | |
57 | + double* vectorPosition, | |
58 | + double const* vectorRefStep) throw(GDIISException, MolDS_base::MolDSException); | |
56 | 59 | void PopOldest(double** vectorError, double** vectorPosition); |
57 | 60 | void PushOldest(double* vectorError, double* vectorPosition); |
58 | 61 | const int sizeErrorVector; |
@@ -64,6 +67,7 @@ private: | ||
64 | 67 | std::string messageTakingGDIISStep; |
65 | 68 | std::string messageSingularGDIISMatrix; |
66 | 69 | std::string messageOnlyOneErrorVector; |
70 | + std::string messageRecalcGDIISStep; | |
67 | 71 | boost::format formatTooSmallLagrangeMultiplier; |
68 | 72 | boost::format formatTooLargeGDIISStep; |
69 | 73 | boost::format formatWrongDirection; |