• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

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

コミットメタ情報

リビジョンa8a0f2ebad34e652113c80007c98e0f86dabe55a (tree)
日時2012-11-07 19:37:22
作者Katsuhiko Nishimra <ktns.87@gmai...>
コミッターKatsuhiko Nishimra

ログメッセージ

Merge trunk into branch gdiis. #28915

git-svn-id: https://svn.sourceforge.jp/svnroot/molds/branches/gdiis@1104 1136aad2-a195-0410-b898-f5ea1d11b9d8

変更サマリ

差分

--- a/src/base/ElectronicStructure.h
+++ b/src/base/ElectronicStructure.h
@@ -43,6 +43,12 @@ public:
4343 virtual void CalcOverlapMOsWithAnotherElectronicStructure(double** overlapMOs,
4444 double const* const* overlapAOs,
4545 const MolDS_base::ElectronicStructure& lhsElectronicStructure) const = 0;
46+ virtual void CalcOverlapSingletSDsWithAnotherElectronicStructure(double** overlapSingletSDs,
47+ double const* const* overlapMOs) const = 0;
48+ virtual void CalcOverlapESsWithAnotherElectronicStructure(double** overlapESs,
49+ double const* const* overlapSingletSDs,
50+ const MolDS_base::ElectronicStructure& lhsElectronicStructure) const = 0;
51+
4652 };
4753
4854 }
--- a/src/base/InputParser.cpp
+++ b/src/base/InputParser.cpp
@@ -1,5 +1,6 @@
11 //************************************************************************//
22 // Copyright (C) 2011-2012 Mikiya Fujii //
3+// Copyright (C) 2011-2012 Michihiro Okuyama //
34 // //
45 // This file is part of MolDS. //
56 // //
@@ -72,6 +73,8 @@ void InputParser::DeleteInstance(){
7273 }
7374
7475 void InputParser::SetMessages(){
76+ this->errorMessageInputFileEmpty
77+ = "Error in base::InputParser::GetInputTerms: Input file is empty.\n";
7578 this->errorMessageNotFoundInputFile
7679 = "Error in base::InputParser::StoreInputTermsFromFile: Not found.\n";
7780 this->errorMessageNonValidExcitedStatesMD
@@ -368,6 +371,15 @@ vector<string> InputParser::GetInputTerms(int argc, char *argv[]) const{
368371 char* fileName = argv[1];
369372 this->StoreInputTermsFromFile(inputTerms,fileName);
370373 }
374+ if (inputTerms.size() == 0) {
375+ char* fileName = argv[1];
376+ stringstream ss;
377+ ss << this->errorMessageInputFileEmpty;
378+ if (argc > 1) {
379+ ss << this->errorMessageInputFile << fileName << endl;
380+ }
381+ throw MolDSException(ss.str());
382+ }
371383 return inputTerms;
372384 }
373385
--- a/src/base/InputParser.h
+++ b/src/base/InputParser.h
@@ -1,5 +1,6 @@
11 //************************************************************************//
22 // Copyright (C) 2011-2012 Mikiya Fujii //
3+// Copyright (C) 2011-2012 Michihiro Okuyama //
34 // //
45 // This file is part of MolDS. //
56 // //
@@ -31,6 +32,7 @@ private:
3132 InputParser();
3233 ~InputParser();
3334 void SetMessages();
35+ std::string errorMessageInputFileEmpty;
3436 std::string errorMessageNotFoundInputFile;
3537 std::string errorMessageNonValidExcitedStatesMD;
3638 std::string errorMessageNonValidExcitedStatesMC;
--- a/src/base/MathUtilities.cpp
+++ b/src/base/MathUtilities.cpp
@@ -22,9 +22,14 @@
2222 #include<sstream>
2323 #include<math.h>
2424 #include<stdexcept>
25+#include<boost/format.hpp>
26+#include"PrintController.h"
2527 #include"MolDSException.h"
28+#include"Uncopyable.h"
29+#include"../wrappers/Lapack.h"
2630 #include"Enums.h"
2731 #include"MathUtilities.h"
32+#include"MallocerFreer.h"
2833 using namespace std;
2934
3035 namespace MolDS_base{
@@ -133,5 +138,21 @@ void CalcRotatingMatrix(double matrix[][3], double sita, CartesianType cartesian
133138 throw MolDSException(ss.str());
134139 }
135140 }
141+
142+// calculate determinant of the matrix
143+double GetDeterminant(double** matrix, int dim){
144+ double determinant=1.0;
145+ int* ipiv=NULL;
146+ MallocerFreer::GetInstance()->Malloc<int>(&ipiv, dim);
147+ MolDS_wrappers::Lapack::GetInstance()->Dgetrf(matrix, ipiv, dim, dim);
148+ for(int i=0; i<dim; i++){
149+ determinant*=matrix[i][i];
150+ if(ipiv[i] != i-1){
151+ determinant *= -1.0;
152+ }
153+ }
154+ MallocerFreer::GetInstance()->Free<int>(&ipiv, dim);
155+ return determinant;
156+}
136157 }
137158
--- a/src/base/MathUtilities.h
+++ b/src/base/MathUtilities.h
@@ -29,6 +29,8 @@ template <typename T> T Max(T a, T b);
2929 template <typename T> T min(T a, T b);
3030 // rotating matrix
3131 void CalcRotatingMatrix(double matrix[][3], double sita, CartesianType cartesianType);
32+// calculate determinant of the matrix. Note taht the matrix will be destroid
33+double GetDeterminant(double** matrix, int dim);
3234 }
3335 #endif
3436
--- a/src/cndo/Cndo2.cpp
+++ b/src/cndo/Cndo2.cpp
@@ -184,6 +184,8 @@ void Cndo2::SetMessages(){
184184 = "Error in cndo::Cndo2::CalcOverlapAOsDifferentConfigurations: Number Atoms in lhs and rhs are different.\n";
185185 this->errorMessageCalcOverlapAOsDifferentConfigurationsOverlapAOsNULL
186186 = "Error in cndo::Cndo2::CalcOverlapAOsDifferentConfigurations: ovelrapAOs is NULL.\n";
187+ this->errorMessageNonExcitedStates
188+ = "Error in cndo::CNDO2::Excited states can not be calculated with CNDO2.\n";
187189 this->errorMessageLhs = "lhs: ";
188190 this->errorMessageRhs = "rhs: ";
189191 this->errorMessageFromState = "\tfrom state = ";
@@ -3580,6 +3582,8 @@ void Cndo2::CalcOverlapMOsWithAnotherElectronicStructure(double** overlapMOs,
35803582 double const* const* rhsFockMatrix = this->fockMatrix;
35813583 double const* const* lhsFockMatrix = lhsElectronicStructure.GetFockMatrix();
35823584 int totalAONumber = this->molecule->GetTotalNumberAOs();
3585+ int usedMONumber = this->molecule->GetTotalNumberValenceElectrons()/2
3586+ +Parameters::GetInstance()->GetActiveVirCIS();
35833587 double** tmpMatrix=NULL;
35843588 try{
35853589 MallocerFreer::GetInstance()->Malloc<double>(&tmpMatrix,totalAONumber,totalAONumber);
@@ -3589,13 +3593,13 @@ void Cndo2::CalcOverlapMOsWithAnotherElectronicStructure(double** overlapMOs,
35893593 double beta=0.0;
35903594 MolDS_wrappers::Blas::GetInstance()->Dgemm(isColumnMajorOverlapAOs,
35913595 isColumnMajorRhsFock,
3592- totalAONumber,totalAONumber,totalAONumber,
3596+ totalAONumber,usedMONumber,totalAONumber,
35933597 alpha,
35943598 overlapAOs,
35953599 rhsFockMatrix,
35963600 beta,
35973601 tmpMatrix);
3598- MolDS_wrappers::Blas::GetInstance()->Dgemm(totalAONumber,totalAONumber,totalAONumber,
3602+ MolDS_wrappers::Blas::GetInstance()->Dgemm(usedMONumber,totalAONumber,totalAONumber,
35993603 lhsFockMatrix,
36003604 tmpMatrix,
36013605 overlapMOs);
@@ -3608,6 +3612,33 @@ void Cndo2::CalcOverlapMOsWithAnotherElectronicStructure(double** overlapMOs,
36083612 MallocerFreer::GetInstance()->Free<double>(&tmpMatrix,totalAONumber,totalAONumber);
36093613 }
36103614
3615+// calculate OverlapSingletSDs matrix between different electronic-structure, S^{SSD}_{ij}.
3616+// i and j are singlet SDs belonging to left and right hand side electronic-structures, respectively.
3617+// The index i=0 means the Hartree-Fock state.
3618+// This overlapsingletSDs are calculated from overlapMOs.
3619+// Note that rhs-electronic-structure is this electronic-structure
3620+// and lhs-electronic-structure is another electronic-structure.
3621+void Cndo2::CalcOverlapSingletSDsWithAnotherElectronicStructure(double** overlapSingletSDs,
3622+ double const* const* overlapMOs) const{
3623+ stringstream ss;
3624+ ss << this->errorMessageNonExcitedStates;
3625+ throw MolDSException(ss.str());
3626+}
3627+
3628+// calculate overlapESs (ES means eigenstate) matrix between different electronic-structure, S^{ES}_{ij}.
3629+// i and j are singlet SDs belonging to left and right hand side electronic-structures, respectively.
3630+// The index i=0 means the ground state.
3631+// This overlapESs is calculated from the overlapsingletSDs.
3632+// Note that rhs-electronic-structure is this electronic-structure
3633+// and lhs-electronic-structure is another electronic-structure.
3634+void Cndo2::CalcOverlapESsWithAnotherElectronicStructure(double** overlapESs,
3635+ double const* const* overlapSingletSDs,
3636+ const MolDS_base::ElectronicStructure& lhsElectronicStructure) const{
3637+ stringstream ss;
3638+ ss << this->errorMessageNonExcitedStates;
3639+ throw MolDSException(ss.str());
3640+}
3641+
36113642 // calculate OverlapAOs matrix. E.g. S_{\mu\nu} in (3.74) in J. A. Pople book.
36123643 void Cndo2::CalcOverlapAOs(double** overlapAOs, const Molecule& molecule) const{
36133644 int totalAONumber = molecule.GetTotalNumberAOs();
--- a/src/cndo/Cndo2.h
+++ b/src/cndo/Cndo2.h
@@ -46,6 +46,11 @@ public:
4646 void CalcOverlapMOsWithAnotherElectronicStructure(double** overlapMOs,
4747 double const* const* overlapAOs,
4848 const MolDS_base::ElectronicStructure& lhsElectronicStructure) const;
49+ virtual void CalcOverlapSingletSDsWithAnotherElectronicStructure(double** overlapSingletSDs,
50+ double const* const* overlapMOs) const;
51+ virtual void CalcOverlapESsWithAnotherElectronicStructure(double** overlapESs,
52+ double const* const* overlapSingletSDs,
53+ const MolDS_base::ElectronicStructure& lhsElectronicStructure) const;
4954 MolDS_base::TheoryType GetTheoryType() const;
5055 protected:
5156 std::string errorMessageAtomA;
@@ -74,6 +79,7 @@ protected:
7479 std::string errorMessageCalcFrequenciesNormalModesBadTheory;
7580 std::string errorMessageFromState;
7681 std::string errorMessageToState;
82+ std::string errorMessageNonExcitedStates;
7783 std::string messageSCFMetConvergence;
7884 std::string messageStartSCF;
7985 std::string messageDoneSCF;
--- a/src/indo/Indo.cpp
+++ b/src/indo/Indo.cpp
@@ -82,6 +82,8 @@ void Indo::SetMessages(){
8282 = "Error in indo::Indo::GetElectronicEnergy: excitedEnergies is NULL\n";
8383 this->errorMessageCalcFrequenciesNormalModesBadTheory
8484 = "Error in indo::Indo::CalcFrequenciesNormalModesBadTheory: INDO is not supported for frequency (normal mode) analysis.\n";
85+ this->errorMessageNonExcitedStates
86+ = "Error in indo::Indo::Excited states can not be calculated with INDO.\n";
8587 this->messageSCFMetConvergence = "\n\n\n\t\tINDO-SCF met convergence criterion(^^b\n\n\n";
8688 this->messageStartSCF = "********** START: INDO-SCF **********\n";
8789 this->messageDoneSCF = "********** DONE: INDO-SCF **********\n\n\n";
--- a/src/nasco/NASCO.cpp
+++ b/src/nasco/NASCO.cpp
@@ -105,13 +105,14 @@ void NASCO::DoNASCO(Molecule& molecule){
105105 molecule.OutputXyzCOC();
106106 molecule.OutputMomenta();
107107
108- // malloc ovelap AOs, MOs, ESs between differentMolecules
108+ // malloc ovelap AOs, MOs, Singlet Slater Determinants, and Eigenstates between differentMolecules
109109 double** overlapAOs = NULL;
110110 double** overlapMOs = NULL;
111+ double** overlapSingletSDs = NULL;
111112 double** overlapESs = NULL;
112113
113114 try{
114- this->MallocOverlapsDifferentMolecules(&overlapAOs, &overlapMOs, &overlapESs, molecule);
115+ this->MallocOverlapsDifferentMolecules(&overlapAOs, &overlapMOs, &overlapSingletSDs, &overlapESs, molecule);
115116 for(int s=0; s<totalSteps; s++){
116117 this->OutputLog(boost::format("%s%d\n") % this->messageStartStepNASCO.c_str() % (s+1) );
117118
@@ -141,7 +142,7 @@ void NASCO::DoNASCO(Molecule& molecule){
141142 // update momenta
142143 this->UpdateMomenta(molecule, matrixForce, dt);
143144
144- // calculate overlaps
145+ // calculate overlaps
145146 currentES->CalcOverlapAOsWithAnotherConfiguration(overlapAOs, tmpMolecule);
146147 cout << "overlapAOs" << endl;
147148 for(int i=0; i<molecule.GetTotalNumberAOs(); i++){
@@ -160,6 +161,31 @@ void NASCO::DoNASCO(Molecule& molecule){
160161 }
161162 cout << endl;
162163 }
164+ cout << endl;
165+
166+ currentES->CalcOverlapSingletSDsWithAnotherElectronicStructure(overlapSingletSDs, overlapMOs);
167+ int dimOverlapSingletSDs = Parameters::GetInstance()->GetActiveOccCIS()
168+ *Parameters::GetInstance()->GetActiveOccCIS()
169+ +1;
170+ cout << "overlap singlet slater determinants" << endl;
171+ for(int i=0; i<dimOverlapSingletSDs; i++){
172+ for(int j=0; j<dimOverlapSingletSDs; j++){
173+ printf("%e\t",overlapSingletSDs[i][j]);
174+ }
175+ cout << endl;
176+ }
177+ cout << endl;
178+
179+ currentES->CalcOverlapESsWithAnotherElectronicStructure(overlapESs, overlapSingletSDs, *tmpES);
180+ int dimOverlapESs = Parameters::GetInstance()->GetNumberElectronicStatesNASCO();
181+ cout << "overlapESs" << endl;
182+ for(int i=0; i<dimOverlapESs; i++){
183+ for(int j=0; j<dimOverlapESs; j++){
184+ printf("%e\t",overlapESs[i][j]);
185+ }
186+ cout << endl;
187+ }
188+ cout << endl;
163189
164190 // Synchronous molecular configuration and electronic states
165191 this->SynchronousMolecularConfiguration(molecule, tmpMolecule);
@@ -179,10 +205,10 @@ void NASCO::DoNASCO(Molecule& molecule){
179205 }
180206 }
181207 catch(MolDSException ex){
182- this->FreeOverlapsDifferentMolecules(&overlapAOs, &overlapMOs, &overlapESs, molecule);
208+ this->FreeOverlapsDifferentMolecules(&overlapAOs, &overlapMOs, &overlapSingletSDs, &overlapESs, molecule);
183209 throw ex;
184210 }
185- this->FreeOverlapsDifferentMolecules(&overlapAOs, &overlapMOs, &overlapESs, molecule);
211+ this->FreeOverlapsDifferentMolecules(&overlapAOs, &overlapMOs, &overlapSingletSDs, &overlapESs, molecule);
186212 this->OutputLog(this->messageEndNASCO);
187213 }
188214
@@ -305,26 +331,36 @@ void NASCO::CheckEnableTheoryType(TheoryType theoryType){
305331
306332 void NASCO::MallocOverlapsDifferentMolecules(double*** overlapAOs,
307333 double*** overlapMOs,
334+ double*** overlapSingletSDs,
308335 double*** overlapESs,
309336 const Molecule& molecule) const{
310337 int dimOverlapAOs = molecule.GetTotalNumberAOs();
311338 int dimOverlapMOs = dimOverlapAOs;
339+ int dimOverlapSingletSDs = Parameters::GetInstance()->GetActiveOccCIS()
340+ *Parameters::GetInstance()->GetActiveVirCIS()
341+ +1;
312342 int dimOverlapESs = Parameters::GetInstance()->GetNumberElectronicStatesNASCO();
313- MallocerFreer::GetInstance()->Malloc<double>(overlapAOs, dimOverlapAOs, dimOverlapAOs);
314- MallocerFreer::GetInstance()->Malloc<double>(overlapMOs, dimOverlapMOs, dimOverlapMOs);
315- MallocerFreer::GetInstance()->Malloc<double>(overlapESs, dimOverlapESs, dimOverlapESs);
343+ MallocerFreer::GetInstance()->Malloc<double>(overlapAOs, dimOverlapAOs, dimOverlapAOs);
344+ MallocerFreer::GetInstance()->Malloc<double>(overlapMOs, dimOverlapMOs, dimOverlapMOs);
345+ MallocerFreer::GetInstance()->Malloc<double>(overlapSingletSDs, dimOverlapSingletSDs, dimOverlapSingletSDs);
346+ MallocerFreer::GetInstance()->Malloc<double>(overlapESs, dimOverlapESs, dimOverlapESs);
316347 }
317348
318349 void NASCO::FreeOverlapsDifferentMolecules(double*** overlapAOs,
319350 double*** overlapMOs,
351+ double*** overlapSingletSDs,
320352 double*** overlapESs,
321353 const MolDS_base::Molecule& molecule) const{
322354 int dimOverlapAOs = molecule.GetTotalNumberAOs();
323355 int dimOverlapMOs = dimOverlapAOs;
356+ int dimOverlapSingletSDs = Parameters::GetInstance()->GetActiveOccCIS()
357+ *Parameters::GetInstance()->GetActiveVirCIS()
358+ +1;
324359 int dimOverlapESs = Parameters::GetInstance()->GetNumberElectronicStatesNASCO();
325- MallocerFreer::GetInstance()->Free<double>(overlapAOs, dimOverlapAOs, dimOverlapAOs);
326- MallocerFreer::GetInstance()->Free<double>(overlapMOs, dimOverlapMOs, dimOverlapMOs);
327- MallocerFreer::GetInstance()->Free<double>(overlapESs, dimOverlapESs, dimOverlapESs);
360+ MallocerFreer::GetInstance()->Free<double>(overlapAOs, dimOverlapAOs, dimOverlapAOs);
361+ MallocerFreer::GetInstance()->Free<double>(overlapMOs, dimOverlapMOs, dimOverlapMOs);
362+ MallocerFreer::GetInstance()->Free<double>(overlapSingletSDs, dimOverlapSingletSDs, dimOverlapSingletSDs);
363+ MallocerFreer::GetInstance()->Free<double>(overlapESs, dimOverlapESs, dimOverlapESs);
328364 }
329365
330366 }
--- a/src/nasco/NASCO.h
+++ b/src/nasco/NASCO.h
@@ -58,10 +58,12 @@ private:
5858 double OutputEnergies(const MolDS_base::ElectronicStructure& electronicStructure, const MolDS_base::Molecule& molecule);
5959 void MallocOverlapsDifferentMolecules(double*** overlapAOs,
6060 double*** overlapMOs,
61+ double*** overlapSingleSDs,
6162 double*** overlapESs,
6263 const MolDS_base::Molecule& molecule) const;
6364 void FreeOverlapsDifferentMolecules(double*** overlapAOs,
6465 double*** overlapMOs,
66+ double*** overlapSingleSDs,
6567 double*** overlapESs,
6668 const MolDS_base::Molecule& molecule) const;
6769 };
--- a/src/optimization/BFGS.cpp
+++ b/src/optimization/BFGS.cpp
@@ -32,6 +32,7 @@
3232 #include"../base/PrintController.h"
3333 #include"../base/MolDSException.h"
3434 #include"../base/Uncopyable.h"
35+#include"../wrappers/Blas.h"
3536 #include"../wrappers/Lapack.h"
3637 #include"../base/Enums.h"
3738 #include"../base/MallocerFreer.h"
@@ -357,90 +358,40 @@ void BFGS::UpdateHessian(double **matrixHessian,
357358 double const* vectorOldForce,
358359 double const* vectorDisplacement) const{
359360 double const* const K = &vectorDisplacement[0]; // K_k in eq. 15 on [SJTO_1983]
360- double* P = NULL; // P_k in eq. 14 on [SJTO_1983]
361- double** PP = NULL; // P_k P_k^T at second term in RHS of Eq. (13) in [SJTO_1983]
362- double* HK = NULL; // H_k K_k at third term on RHS of Eq. (13) in [SJTO_1983]
363- double** HKKH = NULL; // H_k K_k K_k^T H_k at third term on RHS of Eq. (13) in [SJTO_1983]
361+ double *P = NULL; // P_k in eq. 14 on [SJTO_1983]
362+ double *HK = NULL; // H_k K_k at third term on RHS of Eq. (13) in [SJTO_1983]
364363 try{
365364 MallocerFreer::GetInstance()->Malloc(&P, dimension);
366- MallocerFreer::GetInstance()->Malloc(&PP, dimension, dimension);
367365 MallocerFreer::GetInstance()->Malloc(&HK, dimension);
368- MallocerFreer::GetInstance()->Malloc(&HKKH, dimension,dimension);
369366 double KHK = 0;
370367 double PK = 0;
371-#pragma omp parallel for schedule(auto)
372- for(int i=0; i<dimension; i++){
373- // initialize P_k according to Eq. (14) in [SJTO_1983]
374- // note: gradient = -1 * force
375- P[i] = - (vectorForce[i] - vectorOldForce[i]);
376- }
368+ // initialize P_k according to Eq. (14) in [SJTO_1983]
369+ // note: gradient = -1 * force
370+ MolDS_wrappers::Blas::GetInstance()->Dcopy(dimension, vectorOldForce, P);
371+ MolDS_wrappers::Blas::GetInstance()->Daxpy(dimension, -1.0, vectorForce, P);
377372
378373 // P_k^T K_k at second term at RHS of Eq. (13) in [SJTO_1983]
379-#pragma omp parallel
380- {
381-#pragma omp for schedule(auto) reduction(+:PK)
382- for(int i=0; i<dimension;i++){
383- PK += P[i] * K[i];
384- }
385-
386- //P_k P_k^T at second term in RHS of Eq. (13) in [SJTO_1983]
387- for(int i=0; i<dimension;i++){
388-#pragma omp for schedule(auto)
389- for(int j=i;j<dimension;j++){
390- PP[i][j] = PP[j][i] = P[i] * P[j];
391- }
392- }
374+ PK = MolDS_wrappers::Blas::GetInstance()->Ddot(dimension, P, K);
393375
394- //H_k K_k at third term on RHS of Eq. (13) in [SJTO_1983]
395-#pragma omp for schedule(auto)
396- for(int i=0; i<dimension; i++){
397- double tmp=0;
398- for(int j=0; j<dimension; j++){
399- tmp += matrixHessian[i][j] * K[j];
400- }
401- HK[i] = tmp;
402- }
403- }
376+ //H_k K_k at third term on RHS of Eq. (13) in [SJTO_1983]
377+ MolDS_wrappers::Blas::GetInstance()->Dsymv(dimension, matrixHessian, K, HK);
404378
405379 //K_k^T H_k K_k at third term on RHS of Eq. (13) in [SJTO_1983]
406-#pragma omp parallel
407- {
408-#pragma omp for schedule(auto) reduction(+:KHK)
409- for(int i=0;i<dimension;i++){
410- KHK += K[i]*HK[i];
411- }
412-
413- //H_k K_k K_k^T H_k at third term on RHS of Eq. (13) in [SJTO_1983]
414- for(int i=0;i<dimension;i++){
415-#pragma omp for schedule(auto)
416- for(int j=i;j<dimension;j++){
417- // H_k K_k = (K_k^T H_k)^T because H_k^T = H_k
418- HKKH[i][j] = HKKH[j][i] = HK[i] * HK[j];
419- }
420- }
421- }
380+ KHK = MolDS_wrappers::Blas::GetInstance()->Ddot(dimension, K, HK);
422381
423382 // Calculate H_k+1 according to Eq. (13) in [SJTO_1983]
424- for(int i=0;i<dimension;i++){
425-#pragma omp parallel for schedule(auto)
426- for(int j=i;j<dimension;j++){
427- matrixHessian[i][j]+= (PP[i][j] / PK
428- - HKKH[i][j] / KHK);
429- matrixHessian[j][i] = matrixHessian[i][j];
430- }
431- }
383+ // Add second term in RHS of Eq. (13) in [SJTO_1983]
384+ MolDS_wrappers::Blas::GetInstance()->Dsyr(dimension, 1.0/PK, P, matrixHessian);
385+ // Add third term in RHS of Eq. (13) in [SJTO_1983]
386+ MolDS_wrappers::Blas::GetInstance()->Dsyr(dimension, -1.0/KHK, HK, matrixHessian);
432387 }
433388 catch(MolDSException ex){
434389 MallocerFreer::GetInstance()->Free(&P, dimension);
435- MallocerFreer::GetInstance()->Free(&PP, dimension, dimension);
436390 MallocerFreer::GetInstance()->Free(&HK, dimension);
437- MallocerFreer::GetInstance()->Free(&HKKH, dimension,dimension);
438391 throw ex;
439392 }
440393 MallocerFreer::GetInstance()->Free(&P, dimension);
441- MallocerFreer::GetInstance()->Free(&PP, dimension, dimension);
442394 MallocerFreer::GetInstance()->Free(&HK, dimension);
443- MallocerFreer::GetInstance()->Free(&HKKH, dimension,dimension);
444395 }
445396
446397 // Level shift eigenvalues of redandant modes to largeEigenvalue
--- a/src/wrappers/Blas.cpp
+++ b/src/wrappers/Blas.cpp
@@ -57,6 +57,66 @@ void Blas::DeleteInstance(){
5757 blas = NULL;
5858 }
5959
60+// vectorY = vectorX
61+// vectorX: n-vector
62+// vectorY: n-vector
63+void Blas::Dcopy(int n,
64+ double const* vectorX,
65+ double * vectorY)const{
66+ int incrementX=1;
67+ int incrementY=1;
68+ this->Dcopy(n, vectorX, incrementX, vectorY, incrementY);
69+}
70+
71+// vectorY = vectorX
72+// vectorX: n-vector
73+// vectorY: n-vector
74+void Blas::Dcopy(int n,
75+ double const* vectorX, int incrementX,
76+ double* vectorY, int incrementY) const{
77+ dcopy(&n, vectorX, &incrementX, vectorY, &incrementY);
78+}
79+
80+// vectorY = alpha*vectorX + vectorY
81+// vectorX: n-vector
82+// vectorY: n-vector
83+void Blas::Daxpy(int n, double alpha,
84+ double const* vectorX,
85+ double* vectorY) const{
86+ int incrementX=1;
87+ int incrementY=1;
88+ this->Daxpy(n, alpha, vectorX, incrementX, vectorY, incrementY);
89+}
90+
91+// vectorY = alpha*vectorX + vectorY
92+// vectorX: n-vector
93+// vectorY: n-vector
94+void Blas::Daxpy(int n, double alpha,
95+ double const* vectorX, int incrementX,
96+ double* vectorY, int incrementY) const{
97+ daxpy(&n, &alpha, vectorX, &incrementX, vectorY, &incrementY);
98+}
99+
100+// returns vectorX^T*vectorY
101+// vectorX: n-vector
102+// vectorY: n-vector
103+double Blas::Ddot(int n,
104+ double const* vectorX,
105+ double const* vectorY) const{
106+ int incrementX=1;
107+ int incrementY=1;
108+ return this->Ddot(n, vectorX, incrementX, vectorY, incrementY);
109+}
110+
111+// returns vectorX^T*vectorY
112+// vectorX: n-vector
113+// vectorY: n-vector
114+double Blas::Ddot(int n,
115+ double const* vectorX, int incrementX,
116+ double const* vectorY, int incrementY)const{
117+ return ddot(&n, vectorX, &incrementX, vectorY, &incrementY);
118+}
119+
60120 // vectorY = matrixA*vectorX
61121 // matrixA: m*n-matrix (matrixA[m][n] in row-major (C/C++ style))
62122 // vectorX: n-vector
@@ -74,7 +134,7 @@ void Blas::Dgemv(int m, int n,
74134 }
75135
76136 // vectorY = alpha*matrixA*vectorX + beta*vectorY
77-// matrixA: m*n-matrix (matrixA[m][n] in row-major (C/C++ style))
137+// matrixA: m*n-matrix
78138 // vectorX: n-vector
79139 // vectorY: m-vector
80140 void Blas::Dgemv(bool isColumnMajorMatrixA,
@@ -99,6 +159,60 @@ void Blas::Dgemv(bool isColumnMajorMatrixA,
99159 dgemv(&transA, &m, &n, &alpha, a, &lda, vectorX, &incrementX, &beta, vectorY, &incrementY);
100160 }
101161
162+// vectorY = matrixA*vectorX
163+// matrixA: n*n-matrix,symmetric (Use the upper triangular part)
164+// vectorX: n-vector
165+// vectorY: n-vector
166+void Blas::Dsymv(int n,
167+ double const* const* matrixA,
168+ double const* vectorX,
169+ double* vectorY) const{
170+ bool isColumnMajorMatrixA = false; // because, in general, C/C++ style is row-major.
171+ int incrementX=1, incrementY=1;
172+ double alpha=1.0, beta=0.0;
173+ this->Dsymv(n, alpha, matrixA, vectorX, incrementX, beta, vectorY, incrementY);
174+}
175+
176+// vectorY = alpha*matrixA*vectorX + beta*vectorY
177+// matrixA: n*n-matrix,symmetric (Use the upper triangular part)
178+// vectorX: n-vector
179+// vectorY: n-vector
180+void Blas::Dsymv(int n, double alpha,
181+ double const* const* matrixA,
182+ double const* vectorX, int incrementX,
183+ double beta,
184+ double* vectorY, int incrementY) const{
185+ double const* a = &matrixA[0][0];
186+ char uploA='U';
187+ int lda = n;
188+ dsymv(&uploA, &n, &alpha, a, &lda, vectorX, &incrementX, &beta, vectorY, &incrementY);
189+}
190+
191+// matrixA = alpha*vectorX*vectorX^T + matrixA
192+// matrixA: n*n-matrix,symmetric (Use the upper triangular part, and copy it to the lower part.)
193+// vectorX: n-matrix
194+void Blas::Dsyr(int n, double alpha,
195+ double const* vectorX,
196+ double ** matrixA)const{
197+ int incrementX=1;
198+ this->Dsyr(n, alpha, vectorX, incrementX, matrixA);
199+}
200+
201+void Blas::Dsyr(int n, double alpha,
202+ double const* vectorX, int incrementX,
203+ double ** matrixA)const{
204+ double* a = &matrixA[0][0];
205+ char uploA='U';
206+ int lda = n;
207+ dsyr(&uploA, &n, &alpha, vectorX, &incrementX, a, &lda);
208+#pragma omp parallel for schedule(auto)
209+ for(int i=0;i<n;i++){
210+ for(int j=i+1;j<n;j++){
211+ matrixA[j][i] = matrixA[i][j];
212+ }
213+ }
214+}
215+
102216 // matrixC = matrixA*matrixB
103217 // matrixA: m*k-matrix (matrixA[m][k] in row-major (C/C++ style))
104218 // matrixB: k*n-matrix (matrixB[k][n] in row-major (C/C++ style))
@@ -115,8 +229,8 @@ void Blas::Dgemm(int m, int n, int k,
115229 }
116230
117231 // matrixC = alpha*matrixA*matrixB + beta*matrixC
118-// matrixA: m*k-matrix (matrixA[m][k] in row-major (C/C++ style))
119-// matrixB: k*n-matrix (matrixB[k][n] in row-major (C/C++ style))
232+// matrixA: m*k-matrix
233+// matrixB: k*n-matrix
120234 // matrixC: m*n-matrix (matrixC[m][n] in row-major (C/C++ style))
121235 void Blas::Dgemm(bool isColumnMajorMatrixA,
122236 bool isColumnMajorMatrixB,
--- a/src/wrappers/Blas.h
+++ b/src/wrappers/Blas.h
@@ -24,6 +24,24 @@ class Blas: public MolDS_base::PrintController, private MolDS_base::Uncopyable{
2424 public:
2525 static Blas* GetInstance();
2626 static void DeleteInstance();
27+ void Dcopy(int n,
28+ double const* vectorX,
29+ double* vectorY) const;
30+ void Dcopy(int n,
31+ double const* vectorX, int incrementX,
32+ double* vectorY, int incrementY) const;
33+ void Daxpy(int n, double alpha,
34+ double const* vectorX,
35+ double* vectorY) const;
36+ void Daxpy(int n, double alpha,
37+ double const* vectorX, int incrementX,
38+ double* vectorY, int incrementY) const;
39+ double Ddot(int n,
40+ double const* vectorX,
41+ double const* vectorY) const;
42+ double Ddot(int n,
43+ double const* vectorX, int incrementX,
44+ double const* vectorY, int incrementY)const;
2745 void Dgemv(int m, int n,
2846 double const* const* matrixA,
2947 double const* vectorX,
@@ -37,6 +55,21 @@ public:
3755 double beta,
3856 double* vectorY,
3957 int incrementY) const;
58+ void Dsymv(int n,
59+ double const* const* matrixA,
60+ double const* vectorX,
61+ double* vectorY) const;
62+ void Dsymv(int n, double alpha,
63+ double const* const* matrixA,
64+ double const* vectorX, int incrementX,
65+ double beta,
66+ double* vectorY, int incrementY) const;
67+ void Dsyr(int n, double alpha,
68+ double const* vectorX,
69+ double ** matrixA)const;
70+ void Dsyr(int n, double alpha,
71+ double const* vectorX, int incrementX,
72+ double ** matrixA)const;
4073 void Dgemm(int m, int n, int k,
4174 double const* const* matrixA,
4275 double const* const* matrixB,
--- a/src/wrappers/Blas_GNU.cpp
+++ b/src/wrappers/Blas_GNU.cpp
@@ -57,6 +57,70 @@ void Blas::DeleteInstance(){
5757 blas = NULL;
5858 }
5959
60+// vectorY = vectorX
61+// vectorX: n-vector
62+// vectorY: n-vector
63+void Blas::Dcopy(int n,
64+ double const* vectorX,
65+ double * vectorY)const{
66+ int incrementX=1;
67+ int incrementY=1;
68+ this->Dcopy(n, vectorX, incrementX, vectorY, incrementY);
69+}
70+
71+// vectorY = vectorX
72+// vectorX: n-vector
73+// vectorY: n-vector
74+void Blas::Dcopy(int n,
75+ double const* vectorX, int incrementX,
76+ double* vectorY, int incrementY) const{
77+ double* x = const_cast<double*>(&vectorX[0]);
78+ cblas_dcopy(n, x, incrementX, vectorY, incrementY);
79+}
80+
81+// vectorY = alpha*vectorX + vectorY
82+// vectorX: n-vector
83+// vectorY: n-vector
84+void Blas::Daxpy(int n, double alpha,
85+ double const* vectorX,
86+ double* vectorY) const{
87+ int incrementX=1;
88+ int incrementY=1;
89+ this->Daxpy(n, alpha, vectorX, incrementX, vectorY, incrementY);
90+}
91+
92+// vectorY = alpha*vectorX + vectorY
93+// vectorX: n-vector
94+// vectorY: n-vector
95+void Blas::Daxpy(int n, double alpha,
96+ double const* vectorX, int incrementX,
97+ double* vectorY, int incrementY) const{
98+ double* x = const_cast<double*>(&vectorX[0]);
99+ cblas_daxpy(n, alpha, x, incrementX, vectorY, incrementY);
100+}
101+
102+// returns vectorX^T*vectorY
103+// vectorX: n-vector
104+// vectorY: n-vector
105+double Blas::Ddot(int n,
106+ double const* vectorX,
107+ double const* vectorY) const{
108+ int incrementX=1;
109+ int incrementY=1;
110+ return this->Ddot(n, vectorX, incrementX, vectorY, incrementY);
111+}
112+
113+// returns vectorX^T*vectorY
114+// vectorX: n-vector
115+// vectorY: n-vector
116+double Blas::Ddot(int n,
117+ double const* vectorX, int incrementX,
118+ double const* vectorY, int incrementY)const{
119+ double* x=const_cast<double*>(vectorX),
120+ * y=const_cast<double*>(vectorY);
121+ return cblas_ddot(n, x, incrementX, y, incrementY);
122+}
123+
60124 // vectorY = matrixA*vectorX
61125 // matrixA: m*n-matrix (matrixA[m][n] in row-major (C/C++ style))
62126 // vectorX: n-vector
@@ -74,7 +138,7 @@ void Blas::Dgemv(int m, int n,
74138 }
75139
76140 // vectorY = alpha*matrixA*vectorX + beta*vectorY
77-// matrixA: m*n-matrix (matrixA[m][n] in row-major (C/C++ style))
141+// matrixA: m*n-matrix
78142 // vectorX: n-vector
79143 // vectorY: m-vector
80144 void Blas::Dgemv(bool isColumnMajorMatrixA,
@@ -101,6 +165,62 @@ void Blas::Dgemv(bool isColumnMajorMatrixA,
101165
102166 }
103167
168+// vectorY = matrixA*vectorX
169+// matrixA: n*n-matrix,symmetric (Use the upper triangular part)
170+// vectorX: n-vector
171+// vectorY: n-vector
172+void Blas::Dsymv(int n,
173+ double const* const* matrixA,
174+ double const* vectorX,
175+ double* vectorY) const{
176+ bool isColumnMajorMatrixA = false; // because, in general, C/C++ style is row-major.
177+ int incrementX=1, incrementY=1;
178+ double alpha=1.0, beta=0.0;
179+ this->Dsymv(n, alpha, matrixA, vectorX, incrementX, beta, vectorY, incrementY);
180+}
181+
182+// vectorY = alpha*matrixA*vectorX + beta*vectorY
183+// matrixA: n*n-matrix,symmetric (Use the upper triangular part)
184+// vectorX: n-vector
185+// vectorY: n-vector
186+void Blas::Dsymv(int n, double alpha,
187+ double const* const* matrixA,
188+ double const* vectorX, int incrementX,
189+ double beta,
190+ double* vectorY, int incrementY) const{
191+ double* a = const_cast<double*>(&matrixA[0][0]);
192+ double* x = const_cast<double*>(&vectorX[0]);
193+ CBLAS_UPLO uploA=CblasUpper;
194+ int lda = n;
195+ cblas_dsymv(CblasRowMajor, uploA, n, alpha, a, lda, x, incrementX, beta, vectorY, incrementY);
196+}
197+
198+// matrixA = alpha*vectorX*vectorX^T + matrixA
199+// matrixA: n*n-matrix,symmetric (Use the upper triangular part, and copy it to the lower part.)
200+// vectorX: n-matrix
201+void Blas::Dsyr(int n, double alpha,
202+ double const* vectorX,
203+ double ** matrixA)const{
204+ int incrementX=1;
205+ this->Dsyr(n, alpha, vectorX, incrementX, matrixA);
206+}
207+
208+void Blas::Dsyr(int n, double alpha,
209+ double const* vectorX, int incrementX,
210+ double ** matrixA)const{
211+ double* a = &matrixA[0][0];
212+ double* x = const_cast<double*>(&vectorX[0]);
213+ CBLAS_UPLO uploA=CblasUpper;
214+ int lda = n;
215+ cblas_dsyr(CblasRowMajor, uploA, n, alpha, x, incrementX, a, lda);
216+#pragma omp parallel for schedule(auto)
217+ for(int i=0;i<n;i++){
218+ for(int j=i+1;j<n;j++){
219+ matrixA[j][i] = matrixA[i][j];
220+ }
221+ }
222+}
223+
104224 // matrixC = matrixA*matrixB
105225 // matrixA: m*k-matrix (matrixA[m][k] in row-major (C/C++ style))
106226 // matrixB: k*n-matrix (matrixB[k][n] in row-major (C/C++ style))
@@ -117,8 +237,8 @@ void Blas::Dgemm(int m, int n, int k,
117237 }
118238
119239 // matrixC = alpha*matrixA*matrixB + beta*matrixC
120-// matrixA: m*k-matrix (matrixA[m][k] in row-major (C/C++ style))
121-// matrixB: k*n-matrix (matrixB[k][n] in row-major (C/C++ style))
240+// matrixA: m*k-matrix
241+// matrixB: k*n-matrix
122242 // matrixC: m*n-matrix (matrixC[m][n] in row-major (C/C++ style))
123243 void Blas::Dgemm(bool isColumnMajorMatrixA,
124244 bool isColumnMajorMatrixB,
--- a/src/wrappers/Lapack.cpp
+++ b/src/wrappers/Lapack.cpp
@@ -320,7 +320,16 @@ int Lapack::Dgetrs(double const* const* matrix, double** b, int size, int nrhs)
320320 // Argument "matrix" is sizeM*sizeN matrix.
321321 // Argument "matrix" will be LU-decomposed.
322322 int Lapack::Dgetrf(double** matrix, int sizeM, int sizeN) const{
323- int* ipiv = (int*) mkl_malloc( sizeof(int)*2*sizeM, 16 );
323+ int* ipiv = (int*)mkl_malloc( sizeof(int)*2*sizeM, 16 );
324+ this->Dgetrf(matrix, ipiv, sizeM, sizeN);
325+ mkl_free(ipiv);
326+ int info = 0;
327+ return info;
328+}
329+
330+// Argument "matrix" is sizeM*sizeN matrix.
331+// Argument "matrix" will be LU-decomposed.
332+int Lapack::Dgetrf(double** matrix, int* ipiv, int sizeM, int sizeN) const{
324333 double* convertedMatrix = (double*)mkl_malloc( sizeof(double)*sizeM*sizeN, 16 );
325334 for(int i=0; i<sizeM; i++){
326335 for(int j=0; j<sizeN; j++){
@@ -334,7 +343,6 @@ int Lapack::Dgetrf(double** matrix, int sizeM, int sizeN) const{
334343 }
335344 }
336345 mkl_free(convertedMatrix);
337- mkl_free(ipiv);
338346 int info = 0;
339347 return info;
340348 }
--- a/src/wrappers/Lapack.h
+++ b/src/wrappers/Lapack.h
@@ -28,6 +28,7 @@ public:
2828 int Dsysv(double const* const* matrix, double* b, int size);
2929 int Dgetrs(double const* const* matrix, double** b, int size, int nrhs) const;
3030 int Dgetrf(double** matrix, int sizeM, int sizeN) const;
31+ int Dgetrf(double** matrix, int* ipiv, int sizeM, int sizeN) const;
3132 private:
3233 Lapack();
3334 ~Lapack();
--- a/src/wrappers/Lapack_GNU.cpp
+++ b/src/wrappers/Lapack_GNU.cpp
@@ -319,7 +319,16 @@ int Lapack::Dgetrs(double const* const* matrix, double** b, int size, int nrhs)
319319 // Argument "matrix" is sizeM*sizeN matrix.
320320 // Argument "matrix" will be LU-decomposed.
321321 int Lapack::Dgetrf(double** matrix, int sizeM, int sizeN) const{
322- int* ipiv = (int*) LAPACKE_malloc( sizeof(int)*2*sizeM );
322+ int* ipiv = (int*)LAPACKE_malloc( sizeof(int)*2*sizeM );
323+ this->Dgetrf(matrix, ipiv, sizeM, sizeN);
324+ LAPACKE_free(ipiv);
325+ int info = 0;
326+ return info;
327+}
328+
329+// Argument "matrix" is sizeM*sizeN matrix.
330+// Argument "matrix" will be LU-decomposed.
331+int Lapack::Dgetrf(double** matrix, int* ipiv, int sizeM, int sizeN) const{
323332 double* convertedMatrix = (double*)LAPACKE_malloc( sizeof(double)*sizeM*sizeN );
324333 for(int i=0; i<sizeM; i++){
325334 for(int j=0; j<sizeN; j++){
@@ -333,7 +342,6 @@ int Lapack::Dgetrf(double** matrix, int sizeM, int sizeN) const{
333342 }
334343 }
335344 LAPACKE_free(convertedMatrix);
336- LAPACKE_free(ipiv);
337345 int info = 0;
338346 return info;
339347 }
--- a/src/zindo/ZindoS.cpp
+++ b/src/zindo/ZindoS.cpp
@@ -30,8 +30,10 @@
3030 #include"../base/PrintController.h"
3131 #include"../base/MolDSException.h"
3232 #include"../base/Uncopyable.h"
33+#include"../wrappers/Blas.h"
3334 #include"../wrappers/Lapack.h"
3435 #include"../base/Enums.h"
36+#include"../base/MathUtilities.h"
3537 #include"../base/MallocerFreer.h"
3638 #include"../base/EularAngle.h"
3739 #include"../base/Parameters.h"
@@ -696,6 +698,124 @@ void ZindoS::CalcDiatomicOverlapAOs2ndDerivativeInDiatomicFrame(double** diatomi
696698 diatomicOverlapAOs2ndDeri[px][px] *= this->overlapAOsCorrectionPi;
697699 }
698700
701+// calculate OverlapSingletSDs matrix between different electronic-structure, S^{SSD}_{ij}.
702+// i and j are singlet SDs belonging to left and right hand side electronic-structures, respectively.
703+// The index i=0 means the Hartree-Fock state.
704+// This overlapSingletSDs are calculated from overlapMOs.
705+// Note that rhs-electronic-structure is this electronic-structure
706+// and lhs-electronic-structure is another electronic-structure.
707+void ZindoS::CalcOverlapSingletSDsWithAnotherElectronicStructure(double** overlapSingletSDs,
708+ double const* const* overlapMOs) const{
709+ int numberOcc = this->molecule->GetTotalNumberValenceElectrons()/2;
710+ double** tmpMatrix1=NULL;
711+ double** tmpMatrix2=NULL;
712+ double** tmpMatrix3=NULL;
713+ MallocerFreer::GetInstance()->Malloc<double>(&tmpMatrix1, numberOcc, numberOcc);
714+ MallocerFreer::GetInstance()->Malloc<double>(&tmpMatrix2, numberOcc, numberOcc);
715+ MallocerFreer::GetInstance()->Malloc<double>(&tmpMatrix3, numberOcc, numberOcc);
716+ double sqrtGroundStateOverlap;
717+ try{
718+ // between ground state
719+ for(int i=0; i<numberOcc; i++){
720+ for(int j=0; j<numberOcc; j++){
721+ tmpMatrix1[i][j] = overlapMOs[i][j];
722+ }
723+ }
724+ sqrtGroundStateOverlap = GetDeterminant(tmpMatrix1, numberOcc);
725+ overlapSingletSDs[0][0] = pow(sqrtGroundStateOverlap,2.0);
726+
727+ for(int k=0; k<this->matrixCISdimension; k++){
728+ // single excitation from I-th (occupied)MO to A-th (virtual)MO
729+ int moI = this->GetActiveOccIndex(*this->molecule, k);
730+ int moA = this->GetActiveVirIndex(*this->molecule, k);
731+ for(int l=0; l<this->matrixCISdimension; l++){
732+ // single excitation from I-th (occupied)MO to A-th (virtual)MO
733+ int moJ = this->GetActiveOccIndex(*this->molecule, l);
734+ int moB = this->GetActiveVirIndex(*this->molecule, l);
735+ for(int i=0; i<numberOcc; i++){
736+ int destMO = i==moI ? moA : i;
737+ for(int j=0; j<numberOcc; j++){
738+ int sourceMO = j==moJ ? moB : j;
739+ tmpMatrix1[i][j] = overlapMOs[destMO][j];
740+ tmpMatrix2[i][j] = overlapMOs[i][sourceMO];
741+ tmpMatrix3[i][j] = overlapMOs[destMO][sourceMO];
742+ }
743+ }
744+ double det1 = GetDeterminant(tmpMatrix1, numberOcc);
745+ double det2 = GetDeterminant(tmpMatrix2, numberOcc);
746+ double det3 = GetDeterminant(tmpMatrix3, numberOcc);
747+ // from ground state to singet SDs
748+ overlapSingletSDs[k+1][0] = sqrtGroundStateOverlap*det1;
749+ // from singet SDs to ground state
750+ overlapSingletSDs[0] [l+1] = sqrtGroundStateOverlap*det2;
751+ // from singet SDs to singlet SDs
752+ overlapSingletSDs[k+1][l+1] = sqrtGroundStateOverlap*det3 + det1*det2;
753+ }
754+ }
755+ }
756+ catch(MolDSException ex){
757+ MallocerFreer::GetInstance()->Free<double>(&tmpMatrix1, numberOcc, numberOcc);
758+ MallocerFreer::GetInstance()->Free<double>(&tmpMatrix2, numberOcc, numberOcc);
759+ MallocerFreer::GetInstance()->Free<double>(&tmpMatrix3, numberOcc, numberOcc);
760+ throw ex;
761+ }
762+ MallocerFreer::GetInstance()->Free<double>(&tmpMatrix1, numberOcc, numberOcc);
763+ MallocerFreer::GetInstance()->Free<double>(&tmpMatrix2, numberOcc, numberOcc);
764+ MallocerFreer::GetInstance()->Free<double>(&tmpMatrix3, numberOcc, numberOcc);
765+}
766+
767+// calculate overlapESs (ES means eigenstate) matrix between different electronic-structure, S^{ES}_{ij}.
768+// i and j are singlet SDs belonging to left and right hand side electronic-structures, respectively.
769+// The index i=0 means the ground state.
770+// This overlapESs is calculated from the overlapsingletSDs.
771+// Note that rhs-electronic-structure is this electronic-structure
772+// and lhs-electronic-structure is another electronic-structure.
773+void ZindoS::CalcOverlapESsWithAnotherElectronicStructure(double** overlapESs,
774+ double const* const* overlapSingletSDs,
775+ const MolDS_base::ElectronicStructure& lhsElectronicStructure) const{
776+ const ElectronicStructure* rhsElectronicStructure = this;
777+ double const* const* rhsMatrixCIS = this->matrixCIS;
778+ double const* const* lhsMatrixCIS = lhsElectronicStructure.GetMatrixCIS();
779+ int dimOverlapSingletSDs = this->matrixCISdimension + 1;
780+ int dimOverlapESs = Parameters::GetInstance()->GetNumberElectronicStatesNASCO();
781+ int groundstate = 0;
782+ // extended CIS matrix includes groundstate althoug matrixCIS does not include groundstate.
783+ double** lhsExtendedMatrixCIS=NULL;
784+ double** rhsExtendedMatrixCIS=NULL;
785+ double** tmpMatrix=NULL;
786+ MallocerFreer::GetInstance()->Malloc<double>(&lhsExtendedMatrixCIS, dimOverlapSingletSDs, dimOverlapSingletSDs);
787+ MallocerFreer::GetInstance()->Malloc<double>(&rhsExtendedMatrixCIS, dimOverlapSingletSDs, dimOverlapSingletSDs);
788+ MallocerFreer::GetInstance()->Malloc<double>(&tmpMatrix, dimOverlapSingletSDs, dimOverlapESs);
789+ lhsExtendedMatrixCIS[groundstate][groundstate] = 1.0;
790+ rhsExtendedMatrixCIS[groundstate][groundstate] = 1.0;
791+ for(int i=1; i<dimOverlapESs; i++){
792+ for(int j=1; j<dimOverlapSingletSDs; j++){
793+ rhsExtendedMatrixCIS[i][j] = rhsMatrixCIS[i-1][j-1];
794+ lhsExtendedMatrixCIS[i][j] = lhsMatrixCIS[i-1][j-1];
795+ }
796+ }
797+ // calc. overlap between eigenstates
798+ bool isColumnMajorOverlapSingletSDs = false;
799+ bool isColumnMajorRhsMatrixCIS = true;
800+ double alpha=1.0;
801+ double beta=0.0;
802+ MolDS_wrappers::Blas::GetInstance()->Dgemm(isColumnMajorOverlapSingletSDs,
803+ isColumnMajorRhsMatrixCIS,
804+ dimOverlapSingletSDs, dimOverlapESs, dimOverlapSingletSDs,
805+ alpha,
806+ overlapSingletSDs,
807+ rhsExtendedMatrixCIS,
808+ beta,
809+ tmpMatrix);
810+ MolDS_wrappers::Blas::GetInstance()->Dgemm(dimOverlapESs, dimOverlapESs, dimOverlapSingletSDs,
811+ lhsExtendedMatrixCIS,
812+ tmpMatrix,
813+ overlapESs);
814+ MallocerFreer::GetInstance()->Free<double>(&lhsExtendedMatrixCIS, dimOverlapSingletSDs, dimOverlapSingletSDs);
815+ MallocerFreer::GetInstance()->Free<double>(&rhsExtendedMatrixCIS, dimOverlapSingletSDs, dimOverlapSingletSDs);
816+ MallocerFreer::GetInstance()->Free<double>(&tmpMatrix, dimOverlapSingletSDs, dimOverlapESs);
817+}
818+
699819 // The order of mol, moJ, moK, moL is consistent with Eq. (9) in [RZ_1973]
700820 double ZindoS::GetMolecularIntegralElement(int moI, int moJ, int moK, int moL,
701821 const Molecule& molecule,
--- a/src/zindo/ZindoS.h
+++ b/src/zindo/ZindoS.h
@@ -29,6 +29,11 @@ public:
2929 virtual ~ZindoS();
3030 void DoCIS();
3131 void OutputCISResults() const;
32+ void CalcOverlapSingletSDsWithAnotherElectronicStructure(double** overlapSingletSDs,
33+ double const* const* overlapMOs) const;
34+ void CalcOverlapESsWithAnotherElectronicStructure(double** overlapESs,
35+ double const* const* overlapSingletSDs,
36+ const MolDS_base::ElectronicStructure& lhsElectronicStructure) const;
3237 protected:
3338 std::string errorMessageDavidsonNotConverged;
3439 std::string errorMessageCalcCISMatrix;