• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

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

Commit MetaInfo

Révisionce896c8ce3c7ae8cbfadc32e4101add78c19e25f (tree)
l'heure2011-07-08 19:20:41
AuteurMikiya Fujii <mikiya.fujii@gmai...>
CommiterMikiya Fujii

Message de Log

CIS-Davidson is implemented. This is implemented with also open MP.

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

Change Summary

Modification

--- a/src/base/InputParser.h
+++ b/src/base/InputParser.h
@@ -48,6 +48,9 @@ private:
4848 string messageCisNumberActiveVir;
4949 string messageCisNumberExcitedStates;
5050 string messageCisDavidson;
51+ string messageCisNormTolerance;
52+ string messageCisMaxIterations;
53+ string messageCisMaxDimensions;
5154 string stringYES;
5255 string stringNO;
5356 string stringSpace;
@@ -93,6 +96,9 @@ private:
9396 string stringCISActiveVir;
9497 string stringCISNStates;
9598 string stringCISDavidson;
99+ string stringCISMaxIter;
100+ string stringCISMaxDimensions;
101+ string stringCISNormTolerance;
96102 void CalcMolecularBasics(Molecule* molecule);
97103 void CalcCisCondition(Molecule* molecule);
98104 void OutputMolecularBasics(Molecule* molecule);
@@ -124,6 +130,9 @@ InputParser::InputParser(){
124130 this->messageCisNumberActiveVir = "\t\tNumber of active Vir.: ";
125131 this->messageCisNumberExcitedStates = "\t\tNumber of excited states: ";
126132 this->messageCisDavidson = "\t\tCIS-Davidson: ";
133+ this->messageCisNormTolerance = "\t\tNorm tolerance for the residual of the Davidson: ";
134+ this->messageCisMaxIterations = "\t\tMax iterations for the Davidson: ";
135+ this->messageCisMaxDimensions = "\t\tMax dimensions for the Davidson: ";
127136 this->stringYES = "yes";
128137 this->stringNO = "no";
129138 this->stringSpace = " ";
@@ -169,6 +178,9 @@ InputParser::InputParser(){
169178 this->stringCISActiveVir = "active_vir";
170179 this->stringCISNStates = "nstates";
171180 this->stringCISDavidson = "davidson";
181+ this->stringCISMaxIter = "max_iter";
182+ this->stringCISMaxDimensions = "max_dim";
183+ this->stringCISNormTolerance = "norm_tol";
172184 }
173185
174186 InputParser::~InputParser(){
@@ -426,12 +438,29 @@ void InputParser::Parse(Molecule* molecule){
426438 }
427439 j++;
428440 }
441+ // max iterations for the Davidson roop
442+ if(inputTerms[j].compare(this->stringCISMaxIter) == 0){
443+ int maxIter = atoi(inputTerms[j+1].c_str());
444+ Parameters::GetInstance()->SetMaxIterationsCIS(maxIter);
445+ j++;
446+ }
447+ // max dimensions for the Davidson expansion
448+ if(inputTerms[j].compare(this->stringCISMaxDimensions) == 0){
449+ int maxDim = atoi(inputTerms[j+1].c_str());
450+ Parameters::GetInstance()->SetMaxDimensionsCIS(maxDim);
451+ j++;
452+ }
453+ // nolm tolerance for the norm of the resiudal vectors of the Davidson.
454+ if(inputTerms[j].compare(this->stringCISNormTolerance) == 0){
455+ double normTol = atof(inputTerms[j+1].c_str());
456+ Parameters::GetInstance()->SetNormToleranceCIS(normTol);
457+ j++;
458+ }
429459 j++;
430460 }
431461 i = j;
432462 }
433463
434-
435464 // theory
436465 if(inputTerms[i].compare(this->stringTheory) == 0){
437466 int j=i+1;
@@ -524,14 +553,17 @@ void InputParser::CalcCisCondition(Molecule* molecule){
524553 }
525554
526555 // check the number of calculated excited states.
527- int numberExcitedStates = Parameters::GetInstance()->GetActiveOccCIS()
528- *Parameters::GetInstance()->GetActiveVirCIS();
556+ int numberSlaterDeterminants = Parameters::GetInstance()->GetActiveOccCIS()
557+ *Parameters::GetInstance()->GetActiveVirCIS();
529558 if(!Parameters::GetInstance()->GetIsDavidsonCIS()){
530- Parameters::GetInstance()->SetNumberExcitedStatesCIS(numberExcitedStates);
559+ Parameters::GetInstance()->SetNumberExcitedStatesCIS(numberSlaterDeterminants);
531560 }
532561 else{
533- if(numberExcitedStates < Parameters::GetInstance()->GetNumberExcitedStatesCIS()){
534- Parameters::GetInstance()->SetNumberExcitedStatesCIS(numberExcitedStates);
562+ if(numberSlaterDeterminants < Parameters::GetInstance()->GetNumberExcitedStatesCIS()){
563+ Parameters::GetInstance()->SetNumberExcitedStatesCIS(numberSlaterDeterminants);
564+ }
565+ if(numberSlaterDeterminants < Parameters::GetInstance()->GetMaxDimensionsCIS()){
566+ Parameters::GetInstance()->SetMaxDimensionsCIS(numberSlaterDeterminants);
535567 }
536568 }
537569
@@ -568,6 +600,9 @@ void InputParser::OutputCisConditions(){
568600 printf("%s",this->messageCisDavidson.c_str());
569601 if(Parameters::GetInstance()->GetIsDavidsonCIS()){
570602 printf("%s\n",this->stringYES.c_str());
603+ printf("%s%d\n",this->messageCisMaxIterations.c_str(),Parameters::GetInstance()->GetMaxIterationsCIS());
604+ printf("%s%d\n",this->messageCisMaxDimensions.c_str(),Parameters::GetInstance()->GetMaxDimensionsCIS());
605+ printf("%s%e\n",this->messageCisNormTolerance.c_str(),Parameters::GetInstance()->GetNormToleranceCIS());
571606 }
572607 else{
573608 printf("%s\n",this->stringNO.c_str());
--- a/src/base/Parameters.h
+++ b/src/base/Parameters.h
@@ -59,6 +59,12 @@ public:
5959 void SetNumberExcitedStatesCIS(int nStates);
6060 bool GetIsDavidsonCIS();
6161 void SetIsDavidsonCIS(bool isDavidsonCIS);
62+ int GetMaxIterationsCIS();
63+ void SetMaxIterationsCIS(int maxIterationsCIS);
64+ int GetMaxDimensionsCIS();
65+ void SetMaxDimensionsCIS(int maxDimensionsCIS);
66+ double GetNormToleranceCIS();
67+ void SetNormToleranceCIS(double normToleranceCIS);
6268 private:
6369 static Parameters* parameters;
6470 Parameters();
@@ -91,6 +97,9 @@ private:
9197 int activeOccCIS;
9298 int activeVirCIS;
9399 int numberExcitedStatesCIS;
100+ int maxIterationsCIS;
101+ int maxDimensionsCIS;
102+ double normToleranceCIS;
94103 bool isDavidsonCIS;
95104 };
96105 Parameters* Parameters::parameters = NULL;
@@ -155,6 +164,9 @@ void Parameters::SetDefaultValues(){
155164 this->activeVirCIS = 10;
156165 this->numberExcitedStatesCIS = 5;
157166 this->isDavidsonCIS = true;
167+ this->maxIterationsCIS = 100;
168+ this->maxDimensionsCIS = 100;
169+ this->normToleranceCIS = pow(10.0, -6.0);
158170 }
159171
160172 double Parameters::GetThresholdSCF(){
@@ -354,6 +366,30 @@ void Parameters::SetIsDavidsonCIS(bool isDavidsonCIS){
354366 this->isDavidsonCIS = isDavidsonCIS;
355367 }
356368
369+int Parameters::GetMaxIterationsCIS(){
370+ return this->maxIterationsCIS;
371+}
372+
373+void Parameters::SetMaxIterationsCIS(int maxIterationsCIS){
374+ this->maxIterationsCIS = maxIterationsCIS;
375+}
376+
377+int Parameters::GetMaxDimensionsCIS(){
378+ return this->maxDimensionsCIS;
379+}
380+
381+void Parameters::SetMaxDimensionsCIS(int maxDimensionsCIS){
382+ this->maxDimensionsCIS = maxDimensionsCIS;
383+}
384+
385+double Parameters::GetNormToleranceCIS(){
386+ return this->normToleranceCIS;
387+}
388+
389+void Parameters::SetNormToleranceCIS(double normToleranceCIS){
390+ this->normToleranceCIS = normToleranceCIS;
391+}
392+
357393 }
358394 #endif
359395
--- a/src/input.in
+++ b/src/input.in
@@ -22,7 +22,10 @@ CIS
2222 davidson yes
2323 active_occ 100
2424 active_vir 100
25- nstates 10
25+ nstates 11
26+ max_iter 200
27+ max_dim 100
28+ norm_tol 0.000001
2629 CIS_END
2730
2831
@@ -80,13 +83,13 @@ CIS_END
8083 //GEOMETRY_END
8184
8285 //metane
83-GEOMETRY
84- C 0.647389 0.820131 0.000000
85- H 1.004043 -0.188679 0.000000
86- H 1.004062 1.324529 0.873652
87- H 1.004062 1.324529 -0.873652
88- H -0.422611 0.820144 0.000000
89-GEOMETRY_END
86+//GEOMETRY
87+// C 0.647389 0.820131 0.000000
88+// H 1.004043 -0.188679 0.000000
89+// H 1.004062 1.324529 0.873652
90+// H 1.004062 1.324529 -0.873652
91+// H -0.422611 0.820144 0.000000
92+//GEOMETRY_END
9093
9194
9295 // c2
@@ -131,12 +134,12 @@ GEOMETRY_END
131134 //GEOMETRY_END
132135
133136 // acetylene
134-//GEOMETRY
135-// C 0.24933 0.0 0.0
136-// C 1.45053 0.0 0.0
137-// H -0.82067 0.0 0.0
138-// H 2.52053 0.0 0.0
139-//GEOMETRY_END
137+GEOMETRY
138+ C 0.24933 0.0 0.0
139+ C 1.45053 0.0 0.0
140+ H -0.82067 0.0 0.0
141+ H 2.52053 0.0 0.0
142+GEOMETRY_END
140143
141144 // acetylene2
142145 //GEOMETRY
--- a/src/mkl_wrapper/LapackWrapper.h
+++ b/src/mkl_wrapper/LapackWrapper.h
@@ -37,7 +37,7 @@ LapackWrapper* LapackWrapper::lapackWrapper = NULL;
3737 LapackWrapper::LapackWrapper(){
3838 this->calculatedDsysvBlockSize = false;
3939 this->dsysvBlockSize = 64;
40- this->errorMessageDsyevdInfo = "Error in mkl_wrapper::LapackWrapper::Dsyevd: info != 0\n";
40+ this->errorMessageDsyevdInfo = "Error in mkl_wrapper::LapackWrapper::Dsyevd: info != 0: info = ";
4141 this->errorMessageDsyevdSize = "Error in mkl_wrapper::LapackWrapper::Dsyevd: size of matirx < 1\n";
4242 this->errorMessageDsysvInfo = "Error in mkl_wrapper::LapackWrapper::Dsysv: info != 0\n";
4343 this->errorMessageDsysvSize = "Error in mkl_wrapper::LapackWrapper::Dsysv: size of matirx < 1\n";
@@ -160,6 +160,7 @@ int LapackWrapper::Dsyevd(double** matrix, double* eigenValues, int size, bool c
160160 if(info != 0){
161161 stringstream ss;
162162 ss << errorMessageDsyevdInfo;
163+ ss << info << endl;
163164 throw MolDSException(ss.str());
164165 }
165166 return info;
--- a/src/zindo/ZindoS.h
+++ b/src/zindo/ZindoS.h
@@ -48,12 +48,46 @@ private:
4848 Atom* atom); // Apendix in [BZ_1979]
4949 double GetNishimotoMatagaTwoEleInt(Atom* atomA, OrbitalType orbitalA,
5050 Atom* atomB, OrbitalType orbitalB); // ref. [MN_1957] and (5a) in [AEZ_1986]
51+ struct MoEnergy{
52+ double energy;
53+ int occIndex;
54+ int virIndex;
55+ int slaterIndex;
56+ };
57+ struct LessMoEnergy { bool operator()(const MoEnergy& rLeft, const MoEnergy& rRight)
58+ const { return rLeft.energy < rRight.energy; } };
5159 void DoesCISDirect();
5260 void DoesCISDavidson();
61+ void CalcRitzVector(double* ritzVector, double** expansionVectors, double** interactionMatrix,
62+ int interactionMatrixDimension, int ritzVectorIndex);
63+ void CalcResidualVectorAndNorm(double* residualVector, double* norm, double* ritzVector,
64+ double* interactionEigenEnergies, int residualVectorIndex);
65+ void SortSingleExcitationSlaterDeterminants(vector<MoEnergy>* moEnergies);
66+ void UpdateExpansionVectors(double** expansionVectors, double* interactionEigenEnergies, double* residualVector,
67+ int interactionMatrixDimension, int* notConvergedStates, int residualVectorIndex);
68+ void CalcInteractionMatrix(double** interactionMatrix, double** expansionVectors, int interactionMatrixDimension);
69+ void FreeDavidsonCISTemporaryMtrices(double*** expansionVectors, double** residualVector, double** ritzVector);
70+ void FreeDavidsonRoopCISTemporaryMtrices(double*** interactionMatrix,
71+ double interactionMatrixDimension,
72+ double** interactionEigenEnergies);
5373 void CalcCISMatrix(double** matrixCIS, int numberOcc, int numberVir);
5474 string errorMessageNishimotoMataga;
75+ string errorMessageDavidsonNotConverged;
76+ string errorMessageDavidsonMaxIter;
77+ string errorMessageDavidsonMaxDim;
5578 string messageStartCIS;
5679 string messageDoneCIS;
80+ string messageStartDirectCIS;
81+ string messageDoneDirectCIS;
82+ string messageStartDavidsonCIS;
83+ string messageDoneDavidsonCIS;
84+ string messageNumIterCIS;
85+ string messageResidualNorm;
86+ string messageDavidsonConverge;
87+ string messageDavidsonReachCISMatrix;
88+ string messageDavidsonGoToDirect;
89+ string messageExcitedStatesEnergies;
90+ string messageExcitedStatesEnergiesTitle;
5791 };
5892
5993 ZindoS::ZindoS() : MolDS_cndo::Cndo2(){
@@ -92,11 +126,25 @@ void ZindoS::SetMessages(){
92126 this->errorMessageNishimotoMataga = "Error in base_zindo::ZindoS::GetNishimotoMatagaTwoEleInt: Invalid orbitalType.\n";
93127 this->errorMessageMolecularIntegralElement
94128 = "Error in zindo::ZindoS::GetMolecularIntegralElement: Non available orbital is contained.\n";
129+ this->errorMessageDavidsonNotConverged = "Error in zindo::ZindoS::DoesCISDavidson: Davidson did not met convergence criterion. \n";
130+ this->errorMessageDavidsonMaxIter = "Davidson roop reaches max_iter=";
131+ this->errorMessageDavidsonMaxDim = "Dimension of the expansion vectors reaches max_dim=";
95132 this->messageSCFMetConvergence = "\n\n\n\t\tZINDO/S-SCF met convergence criterion(^^b\n\n\n";
96133 this->messageStartSCF = "********** START: ZINDO/S-SCF **********\n";
97134 this->messageDoneSCF = "********** DONE: ZINDO/S-SCF **********\n\n\n";
98135 this->messageStartCIS = "********** START: ZINDO/S-CIS **********\n";
99136 this->messageDoneCIS = "********** DONE: ZINDO/S-CIS **********\n\n\n";
137+ this->messageStartDirectCIS = "\t====== START: Direct-CIS =====\n\n";
138+ this->messageDoneDirectCIS = "\t====== DONE: Direct-CIS =====\n\n\n";
139+ this->messageStartDavidsonCIS = "\t====== START: Davidson-CIS =====\n";
140+ this->messageDoneDavidsonCIS = "\t====== DONE: Davidson-CIS =====\n\n\n";
141+ this->messageNumIterCIS = "\tDavidson iter=";
142+ this->messageResidualNorm = "-th excited: norm of the residual = ";
143+ this->messageDavidsonConverge = "\n\n\t\tDavidson for ZINDO/S-CIS met convergence criterion(^^b\n\n\n";
144+ this->messageDavidsonReachCISMatrix = "\n\t\tDimension of the expansion vectors reaches to the dimension of the CIS-matrix.\n";
145+ this->messageDavidsonGoToDirect = "\t\tHence, we go to the Direct-CIS.\n\n";
146+ this->messageExcitedStatesEnergies = "\tExcitation energies:\n";
147+ this->messageExcitedStatesEnergiesTitle = "\t\t| i-th | e[a.u.] | e[eV] | \n";
100148 }
101149
102150 void ZindoS::SetEnableAtomTypes(){
@@ -621,6 +669,33 @@ double ZindoS::GetMolecularIntegralElement(int moI, int moJ, int moK, int moL,
621669 void ZindoS::DoesCIS(){
622670 cout << this->messageStartCIS;
623671
672+ int numberOcc = Parameters::GetInstance()->GetActiveOccCIS();
673+ int numberVir = Parameters::GetInstance()->GetActiveVirCIS();
674+
675+ // malloc or initialize CIS matrix
676+ if(this->matrixCIS == NULL){
677+ this->matrixCISdimension = numberOcc*numberVir;
678+ this->matrixCIS = MallocerFreer::GetInstance()->MallocDoubleMatrix2d(this->matrixCISdimension,
679+ this->matrixCISdimension);
680+ }
681+ else{
682+ MallocerFreer::GetInstance()->InitializeDoubleMatrix2d(this->matrixCIS,
683+ this->matrixCISdimension,
684+ this->matrixCISdimension);
685+ }
686+
687+ // malloc or initialize CIS eigen vector
688+ if(this->excitedEnergies == NULL){
689+ this->excitedEnergies = MallocerFreer::GetInstance()->MallocDoubleMatrix1d(this->matrixCISdimension);
690+ }
691+ else{
692+ MallocerFreer::GetInstance()->InitializeDoubleMatrix1d(this->excitedEnergies, this->matrixCISdimension);
693+ }
694+
695+ // calculate CIS matrix
696+ this->CalcCISMatrix(matrixCIS, numberOcc, numberVir);
697+
698+ // calculate excited energies
624699 if(Parameters::GetInstance()->GetIsDavidsonCIS()){
625700 this->DoesCISDavidson();
626701 }
@@ -629,55 +704,325 @@ void ZindoS::DoesCIS(){
629704 }
630705
631706 // output eigen energies
707+ cout << this->messageExcitedStatesEnergies;
708+ cout << this->messageExcitedStatesEnergiesTitle;
709+ double eV2AU = Parameters::GetInstance()->GetEV2AU();
632710 for(int k=0; k<Parameters::GetInstance()->GetNumberExcitedStatesCIS(); k++){
633- printf("%d-th excited energy: %e\n",k+1, this->excitedEnergies[k]);
711+ printf("\t\t %d\t%e\t%e\n",k+1, this->excitedEnergies[k], this->excitedEnergies[k]/eV2AU);
634712 }
635713 cout << endl;
636714 cout << this->messageDoneCIS;
637715 }
638716
639-void ZindoS::DoesCISDavidson(){
640- // ToDo: CIS-Davidson
641- stringstream ss;
642- ss << "CIS-Davidson (ZindoS::DoesCISDavidson()) is not implemented yet.\n\n";
643- throw MolDSException(ss.str());
717+void ZindoS::SortSingleExcitationSlaterDeterminants(vector<MoEnergy>* moEnergies){
718+
719+ int numberOcc = Parameters::GetInstance()->GetActiveOccCIS();
720+ int numberVir = Parameters::GetInstance()->GetActiveVirCIS();
721+ for(int k=0; k<numberOcc*numberVir; k++){
722+ // single excitation from I-th (occupied)MO to A-th (virtual)MO
723+ int moI = this->molecule->GetTotalNumberValenceElectrons()/2 - (k/numberVir) -1;
724+ int moA = this->molecule->GetTotalNumberValenceElectrons()/2 + (k%numberVir);
725+
726+ MoEnergy moEnergy = {this->energiesMO[moA] - this->energiesMO[moI], moI, moA, k};
727+ moEnergies->push_back(moEnergy);
728+ }
729+ sort(moEnergies->begin(), moEnergies->end(), LessMoEnergy());
644730 }
645731
646-void ZindoS::DoesCISDirect(){
732+// This method is used for Davidson
733+void ZindoS::CalcRitzVector(double* ritzVector, double** expansionVectors, double** interactionMatrix,
734+ int interactionMatrixDimension, int ritzVectorIndex){
735+
736+ for(int j=0; j<this->matrixCISdimension; j++){
737+ ritzVector[j] = 0.0;
738+ for(int k=0; k<interactionMatrixDimension; k++){
739+ ritzVector[j] += expansionVectors[j][k]*interactionMatrix[ritzVectorIndex][k];
740+ }
741+ }
742+}
743+
744+// This method is used for Davidson
745+void ZindoS::CalcResidualVectorAndNorm(double* residualVector, double* norm, double* ritzVector,
746+ double* interactionEigenEnergies, int residualVectorIndex){
747+
748+ double sqNorm = 0.0;
749+ for(int j=0; j<this->matrixCISdimension; j++){
750+ residualVector[j] = interactionEigenEnergies[residualVectorIndex] * ritzVector[j];
751+ for(int k=0; k<this->matrixCISdimension; k++){
752+ double value = j<=k ? this->matrixCIS[j][k] : this->matrixCIS[k][j];
753+ residualVector[j] -= value*ritzVector[k];
754+ }
755+ sqNorm += pow(residualVector[j],2.0);
756+ }
757+ *norm = sqrt(sqNorm);
758+}
759+
760+// This method is used for Davidson
761+void ZindoS::UpdateExpansionVectors(double** expansionVectors, double* interactionEigenEnergies, double* residualVector,
762+ int interactionMatrixDimension, int* notConvergedStates, int residualVectorIndex){
763+
764+ double newExpansionVector[this->matrixCISdimension];
765+
766+ // calculate new expansion vector from residual vector
767+ for(int j=0; j<this->matrixCISdimension; j++){
768+ double temp = interactionEigenEnergies[residualVectorIndex]-this->matrixCIS[j][j];
769+ if(temp == 0.0){
770+ // prevent dividing by 0.
771+ temp = pow(10,-100);
772+ }
773+ newExpansionVector[j]=pow(temp, -1.0)*residualVector[j];
774+ }
775+
776+ // orthonormalize old expansion vectors and new expansion vector
777+ for(int k=0; k<interactionMatrixDimension+*notConvergedStates; k++){
778+ double overlap=0.0;
779+ for(int j=0; j<this->matrixCISdimension; j++){
780+ overlap += expansionVectors[j][k] * newExpansionVector[j];
781+ }
782+ for(int j=0; j<this->matrixCISdimension; j++){
783+ newExpansionVector[j] -= overlap*expansionVectors[j][k];
784+ }
785+ }
786+
787+ // add new expansion vector to old expansion vectors
788+ double sqNormNewExpVect = 0.0;
789+ for(int j=0; j<this->matrixCISdimension; j++){
790+ sqNormNewExpVect += pow(newExpansionVector[j],2.0);
791+ }
792+ double normNewExpVect = sqrt(sqNormNewExpVect);
793+ for(int j=0; j<this->matrixCISdimension; j++){
794+ expansionVectors[j][interactionMatrixDimension+*notConvergedStates]
795+ = pow(normNewExpVect,-1.0)*newExpansionVector[j];
796+ }
797+ *notConvergedStates += 1;
798+}
799+
800+// This method is used for Davidson
801+void ZindoS::CalcInteractionMatrix(double** interactionMatrix, double** expansionVectors, int interactionMatrixDimension){
802+
803+ for(int i=0; i<interactionMatrixDimension; i++){
804+ for(int j=i; j<interactionMatrixDimension; j++){
805+ for(int a=0; a<this->matrixCISdimension; a++){
806+ for(int b=0; b<this->matrixCISdimension; b++){
807+ double value = a<=b ? this->matrixCIS[a][b] : this->matrixCIS[b][a];
808+ interactionMatrix[i][j] += expansionVectors[a][i]
809+ *value
810+ *expansionVectors[b][j];
811+ }
812+ }
813+ }
814+ }
815+}
816+
817+void ZindoS::DoesCISDavidson(){
818+ cout << this->messageStartDavidsonCIS;
647819
648820 int numberOcc = Parameters::GetInstance()->GetActiveOccCIS();
649821 int numberVir = Parameters::GetInstance()->GetActiveVirCIS();
650822 int numberExcitedStates = Parameters::GetInstance()->GetNumberExcitedStatesCIS();
823+ int maxIter = Parameters::GetInstance()->GetMaxIterationsCIS();
824+ int maxDim = Parameters::GetInstance()->GetMaxDimensionsCIS();
825+ double normTol = Parameters::GetInstance()->GetNormToleranceCIS();
826+ bool convergeExcitedStates[numberExcitedStates];
827+ int interactionMatrixDimension;
828+ bool reachMaxDim;
829+ bool allConverged;
830+ int notConvergedStates;
831+ bool goToDirectCIS;
832+ double** expansionVectors = NULL;
833+ double* ritzVector = NULL;
834+ double* residualVector = NULL;
835+
836+ // malloc
837+ expansionVectors = MallocerFreer::GetInstance()->MallocDoubleMatrix2d(this->matrixCISdimension, maxDim);
838+ ritzVector = MallocerFreer::GetInstance()->MallocDoubleMatrix1d(this->matrixCISdimension);
839+ residualVector = MallocerFreer::GetInstance()->MallocDoubleMatrix1d(this->matrixCISdimension);
840+
841+ try{
842+ // sort single excitation slater determinants
843+ vector<MoEnergy> moEnergies;
844+ this->SortSingleExcitationSlaterDeterminants(&moEnergies);
845+
846+ // set initial expansion vectors and initial conveged vectors
847+ for(int k=0; k<numberExcitedStates; k++){
848+ expansionVectors[moEnergies[k].slaterIndex][k] = 1.0;
849+ convergeExcitedStates[k] = false;
850+ }
651851
652- // malloc CIS matrix
653- if(this->matrixCIS == NULL){
654- this->matrixCISdimension = numberExcitedStates;
655- this->matrixCIS = MallocerFreer::GetInstance()->MallocDoubleMatrix2d(this->matrixCISdimension,
656- this->matrixCISdimension);
852+ interactionMatrixDimension = 0;
853+ reachMaxDim = false;
854+ goToDirectCIS = false;
855+ // Davidson roop
856+ for(int k=0; k<maxIter; k++){
857+ cout << messageNumIterCIS << k << endl;
858+
859+ // calculate dimension of the interaction matrix (= number of the expansion vectors).
860+ for(int i=0; i<numberExcitedStates; i++){
861+ if(!convergeExcitedStates[i]){
862+ interactionMatrixDimension += 1;
863+ }
864+ }
865+
866+ // malloc interaction matrix and etc.
867+ double** interactionMatrix = NULL;
868+ double* interactionEigenEnergies = NULL;
869+ interactionMatrix = MallocerFreer::GetInstance()->MallocDoubleMatrix2d
870+ (interactionMatrixDimension, interactionMatrixDimension);
871+ interactionEigenEnergies = MallocerFreer::GetInstance()->MallocDoubleMatrix1d(interactionMatrixDimension);
872+
873+ try{
874+
875+ // calculate interaction matrix
876+ this->CalcInteractionMatrix(interactionMatrix, expansionVectors, interactionMatrixDimension);
877+
878+ // diagonalize interaction matrix
879+ bool calcEigenVectors = true;
880+ MolDS_mkl_wrapper::LapackWrapper::GetInstance()->Dsyevd(interactionMatrix,
881+ interactionEigenEnergies,
882+ interactionMatrixDimension,
883+ calcEigenVectors);
884+
885+ // check convergence of all excited states
886+ notConvergedStates=0;
887+ allConverged = true;
888+ for(int i=0; i<numberExcitedStates; i++){
889+
890+ // calculate i-th ritz vector
891+ this->CalcRitzVector(ritzVector, expansionVectors, interactionMatrix, interactionMatrixDimension, i);
892+
893+ // calculate i-th residual vector and the norm of the residual vector
894+ double norm = 0.0;
895+ this->CalcResidualVectorAndNorm(residualVector, &norm, ritzVector, interactionEigenEnergies, i);
896+
897+ // output norm of residual vector
898+ cout << "\t " << i+1 << this->messageResidualNorm << norm << endl;
899+ if(i == numberExcitedStates-1){
900+ cout << endl;
901+ }
902+
903+ // check tolerance for the norm of the residual vector.
904+ if(norm < normTol){
905+ convergeExcitedStates[i] = true;
906+ }
907+ else{
908+ convergeExcitedStates[i] = false;
909+ allConverged = false;
910+ if(interactionMatrixDimension+notConvergedStates == maxDim && maxDim !=this->matrixCISdimension){
911+ reachMaxDim = true;
912+ break;
913+ }
914+ else if(interactionMatrixDimension+notConvergedStates == this->matrixCISdimension){
915+ goToDirectCIS = true;
916+ break;
917+ }
918+
919+ // update expansion vectors
920+ this->UpdateExpansionVectors(expansionVectors, interactionEigenEnergies, residualVector,
921+ interactionMatrixDimension, &notConvergedStates, i);
922+
923+ }
924+ }
925+
926+ if(allConverged){
927+ // copy to cis eigen vector and value
928+ for(int i=0; i<numberExcitedStates; i++){
929+ this->excitedEnergies[i] = interactionEigenEnergies[i];
930+ this->CalcRitzVector(ritzVector, expansionVectors, interactionMatrix, interactionMatrixDimension, i);
931+ for(int j=0; j<this->matrixCISdimension; j++){
932+ this->matrixCIS[i][j] = ritzVector[j];
933+ }
934+ }
935+ }
936+ }
937+ catch(MolDSException ex){
938+ this->FreeDavidsonRoopCISTemporaryMtrices(&interactionMatrix,
939+ interactionMatrixDimension,
940+ &interactionEigenEnergies);
941+ throw ex;
942+ }
943+ this->FreeDavidsonRoopCISTemporaryMtrices(&interactionMatrix,
944+ interactionMatrixDimension,
945+ &interactionEigenEnergies);
946+
947+ // stop the Davidson roop
948+ if(allConverged){
949+ cout << this->messageDavidsonConverge;
950+ break;
951+ }
952+ else if(!allConverged && goToDirectCIS){
953+ cout << this->messageDavidsonReachCISMatrix;
954+ cout << this->messageDavidsonGoToDirect;
955+ break;
956+ }
957+ else if(!allConverged && reachMaxDim){
958+ stringstream ss;
959+ ss << endl;
960+ ss << this->errorMessageDavidsonNotConverged;
961+ ss << this->errorMessageDavidsonMaxDim << maxDim << endl;
962+ throw MolDSException(ss.str());
963+ }
964+ else if(!allConverged && k==maxIter-1){
965+ stringstream ss;
966+ ss << this->errorMessageDavidsonNotConverged;
967+ ss << this->errorMessageDavidsonMaxIter << maxIter << endl;
968+ throw MolDSException(ss.str());
969+ }
970+
971+ }// end Davidson roop
657972 }
658- else{
659- MallocerFreer::GetInstance()->InitializeDoubleMatrix2d(this->matrixCIS,
660- this->matrixCISdimension,
661- this->matrixCISdimension);
973+ catch(MolDSException ex){
974+ this->FreeDavidsonCISTemporaryMtrices(&expansionVectors, &residualVector, &ritzVector);
975+ throw ex;
662976 }
977+ this->FreeDavidsonCISTemporaryMtrices(&expansionVectors, &residualVector, &ritzVector);
663978
664- // malloc CIS eigen vector
665- if(this->excitedEnergies == NULL){
666- this->excitedEnergies = MallocerFreer::GetInstance()->MallocDoubleMatrix1d(this->matrixCISdimension);
979+ cout << this->messageDoneDavidsonCIS;
980+ // change algorithm from Davidso to direct
981+ if(goToDirectCIS){
982+ this->DoesCISDirect();
667983 }
668- else{
669- MallocerFreer::GetInstance()->InitializeDoubleMatrix1d(this->excitedEnergies, this->matrixCISdimension);
984+
985+}
986+
987+void ZindoS::FreeDavidsonCISTemporaryMtrices(double*** expansionVectors, double** residualVector, double** ritzVector){
988+
989+ if(*expansionVectors != NULL){
990+ MallocerFreer::GetInstance()->FreeDoubleMatrix2d(expansionVectors, this->matrixCISdimension);
991+ //cout << "expansion vectors deleted\n";
992+ }
993+ if(*residualVector != NULL){
994+ MallocerFreer::GetInstance()->FreeDoubleMatrix1d(residualVector);
995+ //cout << "residual vector deleted\n";
996+ }
997+ if(*ritzVector != NULL){
998+ MallocerFreer::GetInstance()->FreeDoubleMatrix1d(ritzVector);
999+ //cout << "ritz vector deleted\n";
6701000 }
6711001
672- // calc CIS matrix
673- this->CalcCISMatrix(matrixCIS, numberOcc, numberVir);
1002+}
6741003
1004+void ZindoS::FreeDavidsonRoopCISTemporaryMtrices(double*** interactionMatrix,
1005+ double interactionMatrixDimension,
1006+ double** interactionEigenEnergies){
1007+ if(*interactionMatrix != NULL){
1008+ MallocerFreer::GetInstance()->FreeDoubleMatrix2d(interactionMatrix, interactionMatrixDimension);
1009+ //cout << "interactionMatrix deleted\n";
1010+ }
1011+ if(*interactionEigenEnergies != NULL){
1012+ MallocerFreer::GetInstance()->FreeDoubleMatrix1d(interactionEigenEnergies);
1013+ //cout << "interactionEigenEnergies deleted\n";
1014+ }
1015+
1016+}
1017+void ZindoS::DoesCISDirect(){
1018+
1019+ cout << this->messageStartDirectCIS;
6751020 bool calcEigenVectors = true;
6761021 MolDS_mkl_wrapper::LapackWrapper::GetInstance()->Dsyevd(this->matrixCIS,
6771022 this->excitedEnergies,
6781023 this->matrixCISdimension,
6791024 calcEigenVectors);
680-
1025+ cout << this->messageDoneDirectCIS;
6811026 }
6821027
6831028 void ZindoS::CalcCISMatrix(double** matrixCIS, int numberOcc, int numberVir){