Revisión | c321747c7526ff3c4f5ca03f73a30b87cb839377 (tree) |
---|---|
Tiempo | 2013-08-23 16:06:31 |
Autor | Katsuhiko Nishimra <ktns.87@gmai...> |
Commiter | Katsuhiko Nishimra |
Implement GEDIIS::SearchMinimum. #31854
git-svn-id: https://svn.sourceforge.jp/svnroot/molds/trunk@1491 1136aad2-a195-0410-b898-f5ea1d11b9d8
@@ -66,13 +66,18 @@ void GEDIIS::SetMessages(){ | ||
66 | 66 | = "Error in optimization::GEDIIS::Optimize: Optimization did not met convergence criterion.\n"; |
67 | 67 | this->messageStartGEDIISStep |
68 | 68 | = "\n========== START: GEDIIS step "; |
69 | + this->messageTakingGEDIISStep | |
70 | + = "Taking GEDIIS step.\n"; | |
71 | + this->messageTakingRFOStep | |
72 | + = "Taking RFO step.\n"; | |
73 | + this->messageDiscardHistory | |
74 | + = "GDIIS: Discarding all entries from history.\n"; | |
69 | 75 | } |
70 | 76 | |
71 | 77 | void GEDIIS::SearchMinimum(boost::shared_ptr<ElectronicStructure> electronicStructure, |
72 | 78 | Molecule& molecule, |
73 | 79 | double* lineSearchedEnergy, |
74 | 80 | bool* obtainesOptimizedStructure) const { |
75 | - throw MolDSException("GEDIIS not yet implemented"); | |
76 | 81 | int elecState = Parameters::GetInstance()->GetElectronicStateIndexOptimization(); |
77 | 82 | double dt = Parameters::GetInstance()->GetTimeWidthOptimization(); |
78 | 83 | int totalSteps = Parameters::GetInstance()->GetTotalStepsOptimization(); |
@@ -83,15 +88,19 @@ void GEDIIS::SearchMinimum(boost::shared_ptr<ElectronicStructure> electronicStru | ||
83 | 88 | double const* const* matrixForce = NULL; |
84 | 89 | double const* vectorForce = NULL; |
85 | 90 | const int dimension = molecule.GetNumberAtoms()*CartesianType_end; |
86 | - double** matrixHessian = NULL; | |
87 | - double* vectorOldForce = NULL; | |
88 | - double* vectorStep = NULL; | |
89 | - double** matrixStep = NULL; | |
90 | - double** matrixOldCoordinates = NULL; | |
91 | - double* vectorOldCoordinates = NULL; | |
92 | - double** matrixDisplacement = NULL; | |
91 | + double** matrixHessian = NULL; | |
92 | + double* vectorOldForce = NULL; | |
93 | + double* vectorStep = NULL; | |
94 | + double** matrixStep = NULL; | |
95 | + double** matrixOldCoordinates = NULL; | |
96 | + double* vectorOldCoordinates = NULL; | |
97 | + double** matrixDisplacement = NULL; | |
98 | + double** matrixGEDIISCoordinates = NULL; | |
99 | + double** matrixGEDIISForce = NULL; | |
100 | + double* vectorGEDIISForce = NULL; | |
93 | 101 | double trustRadius = Parameters::GetInstance()->GetInitialTrustRadiusOptimization(); |
94 | 102 | const double maxNormStep = Parameters::GetInstance()->GetMaxNormStepOptimization(); |
103 | + GEDIISHistory history; | |
95 | 104 | |
96 | 105 | try{ |
97 | 106 | // initialize Hessian with unit matrix |
@@ -108,6 +117,9 @@ void GEDIIS::SearchMinimum(boost::shared_ptr<ElectronicStructure> electronicStru | ||
108 | 117 | matrixForce = electronicStructure->GetForce(elecState); |
109 | 118 | vectorForce = &matrixForce[0][0]; |
110 | 119 | |
120 | + // Add initial entry into GEDIIS history | |
121 | + history.AddEntry(lineSearchCurrentEnergy, molecule, matrixForce); | |
122 | + | |
111 | 123 | for(int s=0; s<totalSteps; s++){ |
112 | 124 | this->OutputLog(boost::format("%s%d\n\n") % this->messageStartGEDIISStep % (s+1)); |
113 | 125 |
@@ -117,23 +129,60 @@ void GEDIIS::SearchMinimum(boost::shared_ptr<ElectronicStructure> electronicStru | ||
117 | 129 | |
118 | 130 | this->StoreMolecularGeometry(matrixOldCoordinates, molecule); |
119 | 131 | |
120 | - // Level shift Hessian redundant modes | |
121 | - this->ShiftHessianRedundantMode(matrixHessian, molecule); | |
122 | - | |
123 | 132 | // Limit the trustRadius to maxNormStep |
124 | 133 | trustRadius=min(trustRadius,maxNormStep); |
125 | 134 | |
135 | + lineSearchInitialEnergy = lineSearchCurrentEnergy; | |
136 | + double preRFOEnergy = lineSearchInitialEnergy; | |
137 | + | |
138 | + MallocerFreer::GetInstance()->Malloc(&matrixGEDIISCoordinates, molecule.GetNumberAtoms(), CartesianType_end); | |
139 | + MallocerFreer::GetInstance()->Malloc(&matrixGEDIISForce, molecule.GetNumberAtoms(), CartesianType_end); | |
140 | + try{ | |
141 | + history.SolveGEDIISEquation(&preRFOEnergy, matrixGEDIISCoordinates, matrixGEDIISForce); | |
142 | + | |
143 | + this->OutputLog(this->messageTakingGEDIISStep); | |
144 | + this->RollbackMolecularGeometry(molecule, matrixGEDIISCoordinates); | |
145 | + | |
146 | + bool tempCanOutputLogs = false; | |
147 | + this->UpdateElectronicStructure(electronicStructure, molecule, requireGuess, tempCanOutputLogs); | |
148 | + lineSearchCurrentEnergy = electronicStructure->GetElectronicEnergy(elecState); | |
149 | + vectorGEDIISForce = &matrixGEDIISForce[0][0]; | |
150 | + } | |
151 | + catch(MolDSException ex){ | |
152 | + //Check whether the exception is from GEDIIS routine | |
153 | + if(!ex.HasKey(GEDIISErrorID)){ | |
154 | + throw ex; | |
155 | + } | |
156 | + else{ | |
157 | + // Show GEDIIS error message | |
158 | + this->OutputLog(ex.What()); | |
159 | + this->OutputLog("\n"); | |
160 | + | |
161 | + // If the error is not about insufficient history | |
162 | + if(ex.GetKeyValue<int>(GEDIISErrorID) != GEDIISNotSufficientHistory){ | |
163 | + history.DiscardEntries(); | |
164 | + } | |
165 | + | |
166 | + // Skip GEDIIS step and proceed to RFO step | |
167 | + preRFOEnergy = lineSearchCurrentEnergy; | |
168 | + vectorGEDIISForce = vectorOldForce; | |
169 | + } | |
170 | + } | |
171 | + this->OutputLog(messageTakingRFOStep); | |
172 | + | |
173 | + // Level shift Hessian redundant modes | |
174 | + this->ShiftHessianRedundantMode(matrixHessian, molecule); | |
175 | + | |
126 | 176 | //Calculate RFO step |
127 | 177 | MallocerFreer::GetInstance()->Malloc(&matrixStep, molecule.GetNumberAtoms(), CartesianType_end); |
128 | 178 | vectorStep = &matrixStep[0][0]; |
129 | 179 | this->CalcRFOStep(vectorStep, matrixHessian, vectorForce, trustRadius, dimension); |
130 | 180 | |
131 | - double approximateChange = this->ApproximateEnergyChange(dimension, matrixHessian, vectorForce, vectorStep); | |
181 | + double approximateChange = this->ApproximateEnergyChange(dimension, matrixHessian, vectorGEDIISForce, vectorStep); | |
132 | 182 | |
133 | 183 | // Take a RFO step |
134 | 184 | bool doLineSearch = false; |
135 | 185 | bool tempCanOutputLogs = false; |
136 | - lineSearchInitialEnergy = lineSearchCurrentEnergy; | |
137 | 186 | if(doLineSearch){ |
138 | 187 | this->LineSearch(electronicStructure, molecule, lineSearchCurrentEnergy, matrixStep, elecState, dt); |
139 | 188 | } |
@@ -147,9 +196,9 @@ void GEDIIS::SearchMinimum(boost::shared_ptr<ElectronicStructure> electronicStru | ||
147 | 196 | this->UpdateElectronicStructure(electronicStructure, molecule, requireGuess, tempCanOutputLogs); |
148 | 197 | lineSearchCurrentEnergy = electronicStructure->GetElectronicEnergy(elecState); |
149 | 198 | } |
150 | - this->OutputMoleculeElectronicStructure(electronicStructure, molecule, this->CanOutputLogs()); | |
199 | + this->UpdateTrustRadius(trustRadius, approximateChange, preRFOEnergy, lineSearchCurrentEnergy); | |
151 | 200 | |
152 | - this->UpdateTrustRadius(trustRadius, approximateChange, lineSearchInitialEnergy, lineSearchCurrentEnergy); | |
201 | + this->OutputMoleculeElectronicStructure(electronicStructure, molecule, this->CanOutputLogs()); | |
153 | 202 | |
154 | 203 | // check convergence |
155 | 204 | if(this->SatisfiesConvergenceCriterion(matrixForce, |
@@ -162,37 +211,44 @@ void GEDIIS::SearchMinimum(boost::shared_ptr<ElectronicStructure> electronicStru | ||
162 | 211 | break; |
163 | 212 | } |
164 | 213 | |
165 | - if(lineSearchCurrentEnergy > lineSearchInitialEnergy){ | |
166 | - this->OutputLog(this->messageHillClimbing); | |
167 | - this->RollbackMolecularGeometry(molecule, matrixOldCoordinates); | |
168 | - lineSearchCurrentEnergy = lineSearchInitialEnergy; | |
169 | - } | |
170 | - | |
171 | 214 | //Calculate displacement (K_k at Eq. (15) in [SJTO_1983]) |
172 | 215 | this->CalcDisplacement(matrixDisplacement, matrixOldCoordinates, molecule); |
173 | 216 | |
174 | 217 | matrixForce = electronicStructure->GetForce(elecState); |
175 | 218 | vectorForce = &matrixForce[0][0]; |
176 | 219 | |
220 | + history.AddEntry(lineSearchCurrentEnergy, molecule, matrixForce); | |
221 | + | |
177 | 222 | // Update Hessian |
178 | 223 | this->UpdateHessian(matrixHessian, dimension, vectorForce, vectorOldForce, &matrixDisplacement[0][0]); |
179 | 224 | |
225 | + // Check for hill climbing | |
226 | + if(lineSearchCurrentEnergy > lineSearchInitialEnergy){ | |
227 | + this->OutputLog(this->messageHillClimbing); | |
228 | + this->RollbackMolecularGeometry(molecule, matrixOldCoordinates); | |
229 | + lineSearchCurrentEnergy = lineSearchInitialEnergy; | |
230 | + } | |
231 | + | |
180 | 232 | } |
181 | 233 | *lineSearchedEnergy = lineSearchCurrentEnergy; |
182 | 234 | } |
183 | 235 | catch(MolDSException ex){ |
184 | 236 | MallocerFreer::GetInstance()->Free(&matrixHessian, dimension, dimension); |
185 | 237 | MallocerFreer::GetInstance()->Free(&vectorOldForce, dimension); |
186 | - MallocerFreer::GetInstance()->Free(&matrixStep, molecule.GetNumberAtoms(), CartesianType_end); | |
187 | - MallocerFreer::GetInstance()->Free(&matrixDisplacement, molecule.GetNumberAtoms(), CartesianType_end); | |
188 | - MallocerFreer::GetInstance()->Free(&matrixOldCoordinates, molecule.GetNumberAtoms(), CartesianType_end); | |
238 | + MallocerFreer::GetInstance()->Free(&matrixStep , molecule.GetNumberAtoms(), CartesianType_end); | |
239 | + MallocerFreer::GetInstance()->Free(&matrixDisplacement , molecule.GetNumberAtoms(), CartesianType_end); | |
240 | + MallocerFreer::GetInstance()->Free(&matrixOldCoordinates , molecule.GetNumberAtoms(), CartesianType_end); | |
241 | + MallocerFreer::GetInstance()->Free(&matrixGEDIISCoordinates, molecule.GetNumberAtoms(), CartesianType_end); | |
242 | + MallocerFreer::GetInstance()->Free(&matrixGEDIISForce , molecule.GetNumberAtoms(), CartesianType_end); | |
189 | 243 | throw ex; |
190 | 244 | } |
191 | 245 | MallocerFreer::GetInstance()->Free(&matrixHessian, dimension, dimension); |
192 | 246 | MallocerFreer::GetInstance()->Free(&vectorOldForce, dimension); |
193 | - MallocerFreer::GetInstance()->Free(&matrixStep, molecule.GetNumberAtoms(), CartesianType_end); | |
194 | - MallocerFreer::GetInstance()->Free(&matrixDisplacement, molecule.GetNumberAtoms(), CartesianType_end); | |
195 | - MallocerFreer::GetInstance()->Free(&matrixOldCoordinates, molecule.GetNumberAtoms(), CartesianType_end); | |
247 | + MallocerFreer::GetInstance()->Free(&matrixStep , molecule.GetNumberAtoms(), CartesianType_end); | |
248 | + MallocerFreer::GetInstance()->Free(&matrixDisplacement , molecule.GetNumberAtoms(), CartesianType_end); | |
249 | + MallocerFreer::GetInstance()->Free(&matrixOldCoordinates , molecule.GetNumberAtoms(), CartesianType_end); | |
250 | + MallocerFreer::GetInstance()->Free(&matrixGEDIISCoordinates, molecule.GetNumberAtoms(), CartesianType_end); | |
251 | + MallocerFreer::GetInstance()->Free(&matrixGEDIISForce , molecule.GetNumberAtoms(), CartesianType_end); | |
196 | 252 | } |
197 | 253 | |
198 | 254 | GEDIIS::GEDIISHistory::GEDIISHistory(){ |
@@ -34,6 +34,7 @@ protected: | ||
34 | 34 | std::string messageStartGEDIISStep; |
35 | 35 | std::string messageTakingGEDIISStep; |
36 | 36 | std::string messageTakingRFOStep; |
37 | + std::string messageDiscardHistory; | |
37 | 38 | |
38 | 39 | class GEDIISHistory{ |
39 | 40 | public: |