• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revision0c1e048209b1eaecdb0fd329442b2c8a8bff4461 (tree)
Zeit2011-02-02 11:57:29
AutorMikiya Fujii <mikiya.fujii@gmai...>
CommiterMikiya Fujii

Log Message

damp and diis are added.

git-svn-id: https://svn.sourceforge.jp/svnroot/molds/MolDS/trunk@74 1136aad2-a195-0410-b898-f5ea1d11b9d8

Ändern Zusammenfassung

Diff

--- a/doc/README.txt
+++ b/doc/README.txt
@@ -20,23 +20,27 @@ SCF:
2020 THEORY_END
2121
2222 -options
23- "max_iter", "rms_density", "damping_thresh", and "damping_weight" are prepared as options.
24- option is "origin" only for setting the origin of the inertia tensor.
25- options are written in inertia-directive in angstrom unit.
26- Center of mass is used as origin when the "origin" is not set.
23+ "max_iter", "rms_density", "damping_thresh", "damping_weight",
24+ "diis_num_error_vect", "diis_start_error", and "diis_end_error" are prepared as options.
2725
2826 Default value of "max_iter" is 100.
2927 Default value of "rms_density" is 10**(-8.0).
30- Default value of "dampingThresh" is 1.
31- Default value of "dampingWeight" is 0.8.
28+ Default value of "damping_thresh" is 1.
29+ Default value of "damping_weight" is 0.8.
30+ Default value of "diis_num_error_vect" is 5.
31+ Default value of "diis_start_error" is 0.01.
32+ Default value of "diis_end_error" is 10**(-8.0).
3233
3334 E.g.
34- INERTIA
35+ SCF
3536 max_iter 200
3637 rms_density 0.00000001
3738 damping_thresh 0.1
3839 damping_weight 0.7
39- INERTIA_END
40+ diis_num_error_vect 6
41+ diis_start_error 0.01
42+ diis_end_error 0.00000001
43+ SCF_END
4044
4145 Principal Axes (Diagonalizing the inertia tensor):
4246 Write "principal_axes" in theory-directive.
--- a/doc/refferences.txt
+++ b/doc/refferences.txt
@@ -7,6 +7,7 @@
77 [RZ_1973] J. Ridley and M. C. Zerner, Theort. Chim. Acta (Berl.) 32, 111 (1973)
88 [RZ_1976] J. E. Ridley and M. C. Zerner, Theort. Chim. Acta (Berl.) 42, 223 (1976)
99 [BZ_1979] A. D. Bacon and M. C. Zerner, Theort. Chim. Acta (Berl.) 53, 21 (1979)
10+[P_1980] P. Pulay, Chem. Phys. Lett. 73, 393 (1980)
1011 [HKLWNZ_1982] Z. S. Herman, R. F. Kirachner, G. H. Loew, U. T. M.-WesterHoff, A. Nazzal, and M. C. Zerner, Inorg. Chem., 21, 46 (1982)
1112 [AEZ_1986] W. P. Anderson, W. D. Edwards, and M. C. Zerner, Inorg. Chem. 25, 2728 (1986)
1213 [BFB_1997] M. A. Blanco, M. Fl{\'o}rez, and M. Bermejo, J. Mol. Struct. 419, 19 (1997)
--- a/src/base/InputParser.h
+++ b/src/base/InputParser.h
@@ -40,6 +40,9 @@ private:
4040 string messageScfRmsDensity;
4141 string messageScfDampingThresh;
4242 string messageScfDampingWeight;
43+ string messageScfDiisNumErrorVect;
44+ string messageScfDiisStartError;
45+ string messageScfDiisEndError;
4346 string stringSpace;
4447 string stringCommentOut;
4548 string stringTheory;
@@ -59,6 +62,9 @@ private:
5962 string stringScfRmsDensity;
6063 string stringScfDampingThresh;
6164 string stringScfDampingWeight;
65+ string stringScfDiisNumErrorVect;
66+ string stringScfDiisStartError;
67+ string stringScfDiisEndError;
6268 string stringInertiaTensor;
6369 string stringInertiaTensorEnd;
6470 string stringInertiaTensorOrigin;
@@ -100,6 +106,9 @@ InputParser::InputParser(){
100106 this->messageScfRmsDensity = "\t\tRMS density: ";
101107 this->messageScfDampingThresh = "\t\tDamping threshold: ";
102108 this->messageScfDampingWeight = "\t\tDamping weight: ";
109+ this->messageScfDiisNumErrorVect = "\t\tDIIS number of error vectors: ";
110+ this->messageScfDiisStartError = "\t\tDIIS starting error: ";
111+ this->messageScfDiisEndError = "\t\tDIIS ending error: ";
103112 this->stringSpace = " ";
104113 this->stringCommentOut = "//";
105114 this->stringTheoryCNDO2 = "cndo/2";
@@ -119,6 +128,9 @@ InputParser::InputParser(){
119128 this->stringScfRmsDensity = "rms_density";
120129 this->stringScfDampingThresh = "damping_thresh";
121130 this->stringScfDampingWeight = "damping_weight";
131+ this->stringScfDiisNumErrorVect = "diis_num_error_vect";
132+ this->stringScfDiisStartError = "diis_start_error";
133+ this->stringScfDiisEndError = "diis_end_error";
122134 this->stringInertiaTensor = "inertia";
123135 this->stringInertiaTensorEnd = "inertia_end";
124136 this->stringInertiaTensorOrigin = "origin";
@@ -261,6 +273,21 @@ void InputParser::Parse(Molecule* molecule){
261273 Parameters::GetInstance()->SetDampingWeightSCF(atof(inputTerms[j+1].c_str()));
262274 j++;
263275 }
276+ // DIIS number of stored error vectors
277+ if(inputTerms[j].compare(this->stringScfDiisNumErrorVect) == 0){
278+ Parameters::GetInstance()->SetDiisNumErrorVectSCF(atoi(inputTerms[j+1].c_str()));
279+ j++;
280+ }
281+ // DIIS starting error
282+ if(inputTerms[j].compare(this->stringScfDiisStartError) == 0){
283+ Parameters::GetInstance()->SetDiisStartErrorSCF(atof(inputTerms[j+1].c_str()));
284+ j++;
285+ }
286+ // DIIS ending error
287+ if(inputTerms[j].compare(this->stringScfDiisEndError) == 0){
288+ Parameters::GetInstance()->SetDiisEndErrorSCF(atof(inputTerms[j+1].c_str()));
289+ j++;
290+ }
264291 j++;
265292 }
266293 i = j;
@@ -456,6 +483,9 @@ void InputParser::OutputScfConditions(){
456483 printf("%s%e\n",this->messageScfRmsDensity.c_str(),Parameters::GetInstance()->GetThresholdSCF());
457484 printf("%s%e\n",this->messageScfDampingThresh.c_str(),Parameters::GetInstance()->GetDampingThreshSCF());
458485 printf("%s%e\n",this->messageScfDampingWeight.c_str(),Parameters::GetInstance()->GetDampingWeightSCF());
486+ printf("%s%d\n",this->messageScfDiisNumErrorVect.c_str(),Parameters::GetInstance()->GetDiisNumErrorVectSCF());
487+ printf("%s%e\n",this->messageScfDiisStartError.c_str(),Parameters::GetInstance()->GetDiisStartErrorSCF());
488+ printf("%s%e\n",this->messageScfDiisEndError.c_str(),Parameters::GetInstance()->GetDiisEndErrorSCF());
459489 cout << "\n";
460490
461491 }
--- a/src/base/Parameters.h
+++ b/src/base/Parameters.h
@@ -23,6 +23,12 @@ public:
2323 void SetDampingThreshSCF(double dampingThreshSCF);
2424 double GetDampingWeightSCF();
2525 void SetDampingWeightSCF(double dampingWeightSCF);
26+ int GetDiisNumErrorVectSCF();
27+ void SetDiisNumErrorVectSCF(int diisNumErrorVectSCF);
28+ double GetDiisStartErrorSCF();
29+ void SetDiisStartErrorSCF(double diisStartErrorSCF);
30+ double GetDiisEndErrorSCF();
31+ void SetDiisEndErrorSCF(double diisEndErrorSCF);
2632 double GetEV2AU();
2733 double GetAngstrom2AU();
2834 double GetKayser2AU();
@@ -62,6 +68,9 @@ private:
6268 int maxIterationsSCF;
6369 double dampingThreshSCF;
6470 double dampingWeightSCF;
71+ int diisNumErrorVectSCF;
72+ double diisStartErrorSCF;
73+ double diisEndErrorSCF;
6574 void SetDefaultValues();
6675 double eV2AU;
6776 double angstrom2AU;
@@ -123,6 +132,9 @@ void Parameters::SetDefaultValues(){
123132 this->maxIterationsSCF = 100;
124133 this->dampingThreshSCF = 1.0;
125134 this->dampingWeightSCF = 0.8;
135+ this->diisNumErrorVectSCF = 5;
136+ this->diisStartErrorSCF = pow(10.0, -2.0);
137+ this->diisEndErrorSCF = pow(10.0, -8.0);
126138 this->currentTheory = CNDO2;
127139 this->gMolin2AU = pow(10.0,5.0)/(6.0221415*9.1095);
128140 this->degree2Radian = M_PI / 180.0;
@@ -175,6 +187,30 @@ void Parameters::SetDampingWeightSCF(double dampingWeightSCF){
175187 this->dampingWeightSCF = dampingWeightSCF;
176188 }
177189
190+int Parameters::GetDiisNumErrorVectSCF(){
191+ return this->diisNumErrorVectSCF;
192+}
193+
194+void Parameters::SetDiisNumErrorVectSCF(int diisNumErrorVectSCF){
195+ this->diisNumErrorVectSCF = diisNumErrorVectSCF;
196+}
197+
198+double Parameters::GetDiisStartErrorSCF(){
199+ return this->diisStartErrorSCF;
200+}
201+
202+void Parameters::SetDiisStartErrorSCF(double diisStartErrorSCF){
203+ this->diisStartErrorSCF = diisStartErrorSCF;
204+}
205+
206+double Parameters::GetDiisEndErrorSCF(){
207+ return this->diisEndErrorSCF;
208+}
209+
210+void Parameters::SetDiisEndErrorSCF(double diisEndErrorSCF){
211+ this->diisEndErrorSCF = diisEndErrorSCF;
212+}
213+
178214 double Parameters::GetEV2AU(){
179215 return this->eV2AU;
180216 }
--- a/src/cndo/Cndo2.h
+++ b/src/cndo/Cndo2.h
@@ -102,6 +102,20 @@ private:
102102 double GetAuxiliaryA(int k, double rho);
103103 double GetAuxiliaryB(int k, double rho);
104104 double GetAuxiliaryD(int la, int lb, int m);
105+ void DoesDamp(double rmsDensity,
106+ double** orbitalElectronPopulation,
107+ double** oldOrbitalElectronPopulation,
108+ Molecule* molecule);
109+ void DoesDIIS(double** orbitalElectronPopulation,
110+ double** oldOrbitalElectronPopulation,
111+ double* atomicElectronPopulation,
112+ double*** diisStoredDensityMatrix,
113+ double*** diisStoredErrorVect,
114+ double** diisErrorProducts,
115+ double* diisErrorCoefficients,
116+ int diisNumErrorVect,
117+ Molecule* molecule,
118+ int step);
105119 void OutputResults(double** fockMatrix, double* energiesMO, double* atomicElectronPopulation, Molecule* molecule);
106120 void CheckEnableAtomType(Molecule* molecule);
107121 void CheckNumberValenceElectrons(Molecule* molecule);
@@ -111,6 +125,11 @@ private:
111125 double** hMatrix,
112126 double** dammyOrbitalElectronPopulation,
113127 double* dammyAtomicElectronPopulation );
128+ void FreeSCFTemporaryMatrices(double** oldOrbitalElectronPopulation,
129+ double*** diisStoredDensityMatrix,
130+ double*** diisStoredErrorVect,
131+ double** diisErrorProducts,
132+ double* diisErrorCoefficients);
114133
115134 };
116135
@@ -289,8 +308,28 @@ void Cndo2::DoesSCF(){
289308 throw MolDSException(ss.str());
290309 }
291310
311+ // diis parameters
312+ int diisNumErrorVect = Parameters::GetInstance()->GetDiisNumErrorVectSCF();
313+
314+
315+ // malloc temporary matrices for scf
292316 double** oldOrbitalElectronPopulation = MallocerFreer::GetInstance()->MallocDoubleMatrix2d
293317 (this->molecule->GetTotalNumberAOs(), this->molecule->GetTotalNumberAOs());
318+
319+ // malloc temporary matrices for diis
320+ double*** diisStoredDensityMatrix = NULL;
321+ double*** diisStoredErrorVect = NULL;
322+ double** diisErrorProducts = NULL;
323+ double* diisErrorCoefficients = NULL;
324+ if(0<diisNumErrorVect){
325+ diisStoredDensityMatrix = MallocerFreer::GetInstance()->MallocDoubleMatrix3d
326+ (diisNumErrorVect, this->molecule->GetTotalNumberAOs(), this->molecule->GetTotalNumberAOs());
327+ diisStoredErrorVect = MallocerFreer::GetInstance()->MallocDoubleMatrix3d
328+ (diisNumErrorVect, this->molecule->GetTotalNumberAOs(), this->molecule->GetTotalNumberAOs());
329+ diisErrorProducts = MallocerFreer::GetInstance()->MallocDoubleMatrix2d(diisNumErrorVect+1, diisNumErrorVect+1);
330+ diisErrorCoefficients = MallocerFreer::GetInstance()->MallocDoubleMatrix1d(diisNumErrorVect+1);
331+ }
332+
294333 try{
295334 // calculate electron integral
296335 this->CalcGammaAB(this->gammaAB, this->molecule);
@@ -298,8 +337,6 @@ void Cndo2::DoesSCF(){
298337
299338 // SCF
300339 double rmsDensity;
301- double dampingWeight = Parameters::GetInstance()->GetDampingWeightSCF();
302- double dampingThresh = Parameters::GetInstance()->GetDampingThreshSCF();
303340 int maxIterationsSCF = Parameters::GetInstance()->GetMaxIterationsSCF();
304341 bool isGuess=true;
305342 for(int i=0; i<maxIterationsSCF; i++){
@@ -312,7 +349,7 @@ void Cndo2::DoesSCF(){
312349 this->orbitalElectronPopulation,
313350 this->atomicElectronPopulation,
314351 isGuess);
315-
352+
316353 // diagonalization
317354 bool calcEigenVectors = true;
318355 MolDS_mkl_wrapper::LapackWrapper::GetInstance()->Dsyevd(this->fockMatrix,
@@ -325,17 +362,6 @@ void Cndo2::DoesSCF(){
325362 this->molecule,
326363 this->fockMatrix);
327364
328- // damping
329- if(dampingThresh < rmsDensity){
330- for(int j=0; j<this->molecule->GetTotalNumberAOs(); j++){
331- for(int k=0; k<this->molecule->GetTotalNumberAOs(); k++){
332- this->orbitalElectronPopulation[j][k] *= (1.0-dampingWeight);
333- this->orbitalElectronPopulation[j][k] += dampingWeight*oldOrbitalElectronPopulation[j][k];
334-
335- }
336- }
337- }
338-
339365 // calc. electron population in each atom.
340366 this->CalcAtomicElectronPopulation(this->atomicElectronPopulation,
341367 this->orbitalElectronPopulation,
@@ -347,13 +373,31 @@ void Cndo2::DoesSCF(){
347373 this->molecule->GetTotalNumberAOs(), &rmsDensity, i)){
348374
349375 cout << this->messageSCFMetConvergence;
350- this->OutputResults(this->fockMatrix,
351- this->energiesMO,
352- this->atomicElectronPopulation,
353- this->molecule);
354-
376+ this->OutputResults(this->fockMatrix, this->energiesMO, this->atomicElectronPopulation, this->molecule);
355377 break;
356378 }
379+ else{
380+
381+ // damping
382+ this->DoesDamp(rmsDensity, this->orbitalElectronPopulation, oldOrbitalElectronPopulation, this->molecule);
383+
384+ // diis
385+ this->DoesDIIS(this->orbitalElectronPopulation,
386+ oldOrbitalElectronPopulation,
387+ this->atomicElectronPopulation,
388+ diisStoredDensityMatrix,
389+ diisStoredErrorVect,
390+ diisErrorProducts,
391+ diisErrorCoefficients,
392+ diisNumErrorVect,
393+ this->molecule,
394+ i);
395+
396+ this->UpdateOldOrbitalElectronPopulation(oldOrbitalElectronPopulation,
397+ this->orbitalElectronPopulation,
398+ this->molecule->GetTotalNumberAOs());
399+
400+ }
357401
358402 // SCF fails
359403 if(i==maxIterationsSCF-1){
@@ -361,27 +405,169 @@ void Cndo2::DoesSCF(){
361405 ss << this->errorMessageSCFNotConverged << maxIterationsSCF << "\n";
362406 throw MolDSException(ss.str());
363407 }
364-
365408 }
366409 }
367410 catch(MolDSException ex){
368- if(oldOrbitalElectronPopulation != NULL){
369- MallocerFreer::GetInstance()->FreeDoubleMatrix2d
370- (oldOrbitalElectronPopulation, this->molecule->GetTotalNumberAOs());
371- oldOrbitalElectronPopulation = NULL;
372- //cout << "oldOrbitalElectronPopulation deleted\n";
373- }
411+ this->FreeSCFTemporaryMatrices(oldOrbitalElectronPopulation,
412+ diisStoredDensityMatrix,
413+ diisStoredErrorVect,
414+ diisErrorProducts,
415+ diisErrorCoefficients);
416+
374417 throw ex;
375418 }
376-
419+ this->FreeSCFTemporaryMatrices(oldOrbitalElectronPopulation,
420+ diisStoredDensityMatrix,
421+ diisStoredErrorVect,
422+ diisErrorProducts,
423+ diisErrorCoefficients);
424+
425+
426+ cout << this->messageDoneSCF;
427+
428+}
429+
430+void Cndo2::FreeSCFTemporaryMatrices(double** oldOrbitalElectronPopulation,
431+ double*** diisStoredDensityMatrix,
432+ double*** diisStoredErrorVect,
433+ double** diisErrorProducts,
434+ double* diisErrorCoefficients){
435+
436+ int diisNumErrorVect = Parameters::GetInstance()->GetDiisNumErrorVectSCF();
377437 if(oldOrbitalElectronPopulation != NULL){
378438 MallocerFreer::GetInstance()->FreeDoubleMatrix2d
379439 (oldOrbitalElectronPopulation, this->molecule->GetTotalNumberAOs());
380440 oldOrbitalElectronPopulation = NULL;
381441 //cout << "oldOrbitalElectronPopulation deleted\n";
382442 }
443+ if(diisStoredDensityMatrix != NULL){
444+ MallocerFreer::GetInstance()->FreeDoubleMatrix3d
445+ (diisStoredDensityMatrix, diisNumErrorVect, this->molecule->GetTotalNumberAOs());
446+ diisStoredDensityMatrix = NULL;
447+ //cout << "diisStoredDensityMatrix deleted\n";
448+ }
449+ if(diisStoredErrorVect != NULL){
450+ MallocerFreer::GetInstance()->FreeDoubleMatrix3d
451+ (diisStoredErrorVect, diisNumErrorVect, this->molecule->GetTotalNumberAOs());
452+ diisStoredErrorVect = NULL;
453+ //cout << "diisStoredErrorVect deleted\n";
454+ }
455+ if(diisErrorProducts != NULL){
456+ MallocerFreer::GetInstance()->FreeDoubleMatrix2d
457+ (diisErrorProducts, diisNumErrorVect+1);
458+ diisErrorProducts = NULL;
459+ //cout << "diisErrorProducts deleted\n";
460+ }
461+ if(diisErrorCoefficients != NULL){
462+ MallocerFreer::GetInstance()->FreeDoubleMatrix1d
463+ (diisErrorCoefficients);
464+ diisErrorCoefficients = NULL;
465+ //cout << "diisErrorCoefficients deleted\n";
466+ }
383467
384- cout << this->messageDoneSCF;
468+}
469+
470+/***
471+ *
472+ * see ref. [P_1980] for diis methods.
473+ *
474+ */
475+void Cndo2::DoesDIIS(double** orbitalElectronPopulation,
476+ double** oldOrbitalElectronPopulation,
477+ double* atomicElectronPopulation,
478+ double*** diisStoredDensityMatrix,
479+ double*** diisStoredErrorVect,
480+ double** diisErrorProducts,
481+ double* diisErrorCoefficients,
482+ int diisNumErrorVect,
483+ Molecule* molecule,
484+ int step){
485+
486+ int totalNumberAOs = molecule->GetTotalNumberAOs();
487+ double diisStartError = Parameters::GetInstance()->GetDiisStartErrorSCF();
488+ double diisEndError = Parameters::GetInstance()->GetDiisEndErrorSCF();
489+
490+ if( 0 < diisNumErrorVect){
491+ for(int m=0; m<diisNumErrorVect-1; m++){
492+ for(int j=0; j<totalNumberAOs; j++){
493+ for(int k=0; k<totalNumberAOs; k++){
494+ diisStoredDensityMatrix[m][j][k] = diisStoredDensityMatrix[m+1][j][k];
495+ diisStoredErrorVect[m][j][k] = diisStoredErrorVect[m+1][j][k];
496+ }
497+ }
498+ }
499+
500+ for(int j=0; j<totalNumberAOs; j++){
501+ for(int k=0; k<totalNumberAOs; k++){
502+ diisStoredDensityMatrix[diisNumErrorVect-1][j][k] = orbitalElectronPopulation[j][k];
503+ diisStoredErrorVect[diisNumErrorVect-1][j][k] = orbitalElectronPopulation[j][k]
504+ -oldOrbitalElectronPopulation[j][k];
505+
506+ }
507+ }
508+
509+ for(int mi=0; mi<diisNumErrorVect-1; mi++){
510+ for(int mj=0; mj<diisNumErrorVect-1; mj++){
511+ diisErrorProducts[mi][mj] = diisErrorProducts[mi+1][mj+1];
512+ }
513+ }
514+
515+ double tempErrorProduct=0.0;
516+ for(int mi=0; mi<diisNumErrorVect; mi++){
517+ tempErrorProduct = 0.0;
518+ for(int j=0; j<totalNumberAOs; j++){
519+ for(int k=0; k<totalNumberAOs; k++){
520+ tempErrorProduct += diisStoredErrorVect[mi][j][k]*diisStoredErrorVect[diisNumErrorVect-1][j][k];
521+ }
522+ }
523+ diisErrorProducts[mi][diisNumErrorVect-1] = tempErrorProduct;
524+ diisErrorProducts[diisNumErrorVect-1][mi] = tempErrorProduct;
525+ diisErrorProducts[mi][diisNumErrorVect] = -1.0;
526+ diisErrorProducts[diisNumErrorVect][mi] = -1.0;
527+ diisErrorCoefficients[mi] = 0.0;
528+ }
529+ diisErrorProducts[diisNumErrorVect][diisNumErrorVect] = 0.0;
530+ diisErrorCoefficients[diisNumErrorVect] = -1.0;
531+
532+ double eMax = 0;
533+ for(int j=0; j<totalNumberAOs; j++){
534+ for(int k=0; k<totalNumberAOs; k++){
535+ eMax = max(eMax, fabs(diisStoredErrorVect[diisNumErrorVect-1][j][k]));
536+ }
537+ }
538+
539+ if(diisNumErrorVect <= step && diisEndError<eMax && eMax<diisStartError){
540+ MolDS_mkl_wrapper::LapackWrapper::GetInstance()->Dsysv(diisErrorProducts,
541+ diisErrorCoefficients,
542+ diisNumErrorVect+1);
543+ for(int j=0; j<totalNumberAOs; j++){
544+ for(int k=0; k<totalNumberAOs; k++){
545+ orbitalElectronPopulation[j][k] = 0.0;
546+ for(int m=0; m<diisNumErrorVect; m++){
547+ orbitalElectronPopulation[j][k] += diisErrorCoefficients[m]*diisStoredDensityMatrix[m][j][k];
548+ }
549+ }
550+ }
551+
552+ // calc. electron population in each atom.
553+ this->CalcAtomicElectronPopulation(atomicElectronPopulation, orbitalElectronPopulation, molecule);
554+ }
555+ }
556+}
557+
558+void Cndo2::DoesDamp(double rmsDensity, double** orbitalElectronPopulation,
559+ double** oldOrbitalElectronPopulation, Molecule* molecule){
560+
561+ double dampingThresh = Parameters::GetInstance()->GetDampingThreshSCF();
562+ double dampingWeight = Parameters::GetInstance()->GetDampingWeightSCF();
563+ if(0.0 < dampingWeight && dampingThresh < rmsDensity){
564+ for(int j=0; j<molecule->GetTotalNumberAOs(); j++){
565+ for(int k=0; k<molecule->GetTotalNumberAOs(); k++){
566+ orbitalElectronPopulation[j][k] *= (1.0 - dampingWeight);
567+ orbitalElectronPopulation[j][k] += dampingWeight*oldOrbitalElectronPopulation[j][k];
568+ }
569+ }
570+ }
385571
386572 }
387573
@@ -596,11 +782,6 @@ bool Cndo2::SatisfyConvergenceCriterion(double** oldOrbitalElectronPopulation,
596782 if(*rmsDensity < Parameters::GetInstance()->GetThresholdSCF()){
597783 satisfy = true;
598784 }
599- else{
600- this->UpdateOldOrbitalElectronPopulation(oldOrbitalElectronPopulation,
601- orbitalElectronPopulation,
602- numberAOs);
603- }
604785
605786 return satisfy;
606787 }
--- a/src/input.in
+++ b/src/input.in
@@ -1,6 +1,6 @@
11 THEORY
2- //cndo/2
3- indo
2+ cndo/2
3+ //indo
44 //zindo/s
55 //none
66 //principal_axes
@@ -9,15 +9,18 @@ THEORY
99 THEORY_END
1010
1111 SCF
12- max_iter 200
13- rms_density 0.00000001
12+ max_iter 50
13+ rms_density 0.000001
1414 damping_thresh 1.0
15- damping_weight 0.7
15+ damping_weight 0.0
16+ diis_num_error_vect 5
17+ diis_start_error 0.002
18+ diis_end_error 0.00000002
1619 SCF_END
1720
1821 CIS
19- activeOcc 100
20- activeVir 100
22+ activeOcc 2
23+ activeVir 2
2124 nstates 1000
2225 CIS_END
2326
--- a/src/mkl_wrapper/LapackWrapper.h
+++ b/src/mkl_wrapper/LapackWrapper.h
@@ -18,24 +18,32 @@ public:
1818 static LapackWrapper* GetInstance();
1919 static void DeleteInstance();
2020 int Dsyevd(double** matrix, double* eigenValues, int size, bool calcEigenVectors);
21+ int Dsysv(double** matrix, double* b, int size);
2122 private:
2223 LapackWrapper();
2324 LapackWrapper(LapackWrapper&);
2425 void operator = (LapackWrapper&);
2526 ~LapackWrapper();
2627 static LapackWrapper* lapackWrapper;
27-
28+ bool calculatedDsysvWorkSize;
29+ int dsysvWorkSize;
2830 string errorMessageDsyevdInfo;
2931 string errorMessageDsyevdSize;
32+ string errorMessageDsysvInfo;
33+ string errorMessageDsysvSize;
3034 };
3135 LapackWrapper* LapackWrapper::lapackWrapper = NULL;
3236
3337 LapackWrapper::LapackWrapper(){
3438 this->errorMessageDsyevdInfo = "Error in mkl_wrapper::LapackWrapper::Dsyevd: info != 0\n";
3539 this->errorMessageDsyevdSize = "Error in mkl_wrapper::LapackWrapper::Dsyevd: size of matirx < 1\n";
40+ this->errorMessageDsysvInfo = "Error in mkl_wrapper::LapackWrapper::Dsysv: info != 0\n";
41+ this->errorMessageDsysvSize = "Error in mkl_wrapper::LapackWrapper::Dsysv: size of matirx < 1\n";
3642 }
3743
3844 LapackWrapper::~LapackWrapper(){
45+ this->calculatedDsysvWorkSize = false;
46+ this->dsysvWorkSize = 64;
3947 }
4048
4149 LapackWrapper* LapackWrapper::GetInstance(){
@@ -154,6 +162,72 @@ int LapackWrapper::Dsyevd(double** matrix, double* eigenValues, int size, bool c
154162 return info;
155163 }
156164
165+/***
166+ *
167+ * Slove matrix*X=b, then we get X by this method.
168+ * The X is stored in b.
169+ *
170+ */
171+int LapackWrapper::Dsysv(double** matrix, double* b, int size){
172+ int info = 0;
173+ int lwork;
174+ char uplo = 'U';
175+ int lda = size;
176+ int ldb = size;
177+ int nrhs = 1;
178+ double* convertedMatrix;
179+ double* work;
180+ int* ipiv;
181+
182+ if(size < 1 ){
183+ stringstream ss;
184+ ss << errorMessageDsysvSize;
185+ throw MolDSException(ss.str());
186+ }
187+
188+ // malloc
189+ ipiv = MallocerFreer::GetInstance()->MallocIntMatrix1d(2*size);
190+ convertedMatrix = MallocerFreer::GetInstance()->MallocDoubleMatrix1d(size*size);
191+
192+ for(int i = 0; i < size; i++){
193+ for(int j = i; j < size; j++){
194+ convertedMatrix[i+j*size] = matrix[i][j];
195+ }
196+ }
197+
198+ // calc. lwork
199+ if(!this->calculatedDsysvWorkSize){
200+ lwork = -1;
201+ double tempWork[3]={0.0, 0.0, 0.0};
202+ dsysv(&uplo, &size, &nrhs, convertedMatrix, &lda, ipiv, b, &ldb, tempWork, &lwork, &info);
203+ this->calculatedDsysvWorkSize = true;
204+ this->dsysvWorkSize = tempWork[0];
205+ }
206+
207+ info = 0;
208+ lwork = this->dsysvWorkSize;
209+ work = MallocerFreer::GetInstance()->MallocDoubleMatrix1d(lwork);
210+
211+ // call Lapack
212+ dsysv(&uplo, &size, &nrhs, convertedMatrix, &lda, ipiv, b, &ldb, work, &lwork, &info);
213+
214+ // free
215+ MallocerFreer::GetInstance()->FreeDoubleMatrix1d(convertedMatrix);
216+ convertedMatrix = NULL;
217+ MallocerFreer::GetInstance()->FreeIntMatrix1d(ipiv);
218+ ipiv = NULL;
219+ MallocerFreer::GetInstance()->FreeDoubleMatrix1d(work);
220+ work = NULL;
221+
222+ if(info != 0){
223+ cout << "info=" << info << endl;
224+ stringstream ss;
225+ ss << errorMessageDsysvInfo;
226+ throw MolDSException(ss.str());
227+ }
228+ return info;
229+}
230+
157231
158232
159233 }