修訂 | a8a0f2ebad34e652113c80007c98e0f86dabe55a (tree) |
---|---|
時間 | 2012-11-07 19:37:22 |
作者 | Katsuhiko Nishimra <ktns.87@gmai...> |
Commiter | 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
@@ -43,6 +43,12 @@ public: | ||
43 | 43 | virtual void CalcOverlapMOsWithAnotherElectronicStructure(double** overlapMOs, |
44 | 44 | double const* const* overlapAOs, |
45 | 45 | 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 | + | |
46 | 52 | }; |
47 | 53 | |
48 | 54 | } |
@@ -1,5 +1,6 @@ | ||
1 | 1 | //************************************************************************// |
2 | 2 | // Copyright (C) 2011-2012 Mikiya Fujii // |
3 | +// Copyright (C) 2011-2012 Michihiro Okuyama // | |
3 | 4 | // // |
4 | 5 | // This file is part of MolDS. // |
5 | 6 | // // |
@@ -72,6 +73,8 @@ void InputParser::DeleteInstance(){ | ||
72 | 73 | } |
73 | 74 | |
74 | 75 | void InputParser::SetMessages(){ |
76 | + this->errorMessageInputFileEmpty | |
77 | + = "Error in base::InputParser::GetInputTerms: Input file is empty.\n"; | |
75 | 78 | this->errorMessageNotFoundInputFile |
76 | 79 | = "Error in base::InputParser::StoreInputTermsFromFile: Not found.\n"; |
77 | 80 | this->errorMessageNonValidExcitedStatesMD |
@@ -368,6 +371,15 @@ vector<string> InputParser::GetInputTerms(int argc, char *argv[]) const{ | ||
368 | 371 | char* fileName = argv[1]; |
369 | 372 | this->StoreInputTermsFromFile(inputTerms,fileName); |
370 | 373 | } |
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 | + } | |
371 | 383 | return inputTerms; |
372 | 384 | } |
373 | 385 |
@@ -1,5 +1,6 @@ | ||
1 | 1 | //************************************************************************// |
2 | 2 | // Copyright (C) 2011-2012 Mikiya Fujii // |
3 | +// Copyright (C) 2011-2012 Michihiro Okuyama // | |
3 | 4 | // // |
4 | 5 | // This file is part of MolDS. // |
5 | 6 | // // |
@@ -31,6 +32,7 @@ private: | ||
31 | 32 | InputParser(); |
32 | 33 | ~InputParser(); |
33 | 34 | void SetMessages(); |
35 | + std::string errorMessageInputFileEmpty; | |
34 | 36 | std::string errorMessageNotFoundInputFile; |
35 | 37 | std::string errorMessageNonValidExcitedStatesMD; |
36 | 38 | std::string errorMessageNonValidExcitedStatesMC; |
@@ -22,9 +22,14 @@ | ||
22 | 22 | #include<sstream> |
23 | 23 | #include<math.h> |
24 | 24 | #include<stdexcept> |
25 | +#include<boost/format.hpp> | |
26 | +#include"PrintController.h" | |
25 | 27 | #include"MolDSException.h" |
28 | +#include"Uncopyable.h" | |
29 | +#include"../wrappers/Lapack.h" | |
26 | 30 | #include"Enums.h" |
27 | 31 | #include"MathUtilities.h" |
32 | +#include"MallocerFreer.h" | |
28 | 33 | using namespace std; |
29 | 34 | |
30 | 35 | namespace MolDS_base{ |
@@ -133,5 +138,21 @@ void CalcRotatingMatrix(double matrix[][3], double sita, CartesianType cartesian | ||
133 | 138 | throw MolDSException(ss.str()); |
134 | 139 | } |
135 | 140 | } |
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 | +} | |
136 | 157 | } |
137 | 158 |
@@ -29,6 +29,8 @@ template <typename T> T Max(T a, T b); | ||
29 | 29 | template <typename T> T min(T a, T b); |
30 | 30 | // rotating matrix |
31 | 31 | 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); | |
32 | 34 | } |
33 | 35 | #endif |
34 | 36 |
@@ -184,6 +184,8 @@ void Cndo2::SetMessages(){ | ||
184 | 184 | = "Error in cndo::Cndo2::CalcOverlapAOsDifferentConfigurations: Number Atoms in lhs and rhs are different.\n"; |
185 | 185 | this->errorMessageCalcOverlapAOsDifferentConfigurationsOverlapAOsNULL |
186 | 186 | = "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"; | |
187 | 189 | this->errorMessageLhs = "lhs: "; |
188 | 190 | this->errorMessageRhs = "rhs: "; |
189 | 191 | this->errorMessageFromState = "\tfrom state = "; |
@@ -3580,6 +3582,8 @@ void Cndo2::CalcOverlapMOsWithAnotherElectronicStructure(double** overlapMOs, | ||
3580 | 3582 | double const* const* rhsFockMatrix = this->fockMatrix; |
3581 | 3583 | double const* const* lhsFockMatrix = lhsElectronicStructure.GetFockMatrix(); |
3582 | 3584 | int totalAONumber = this->molecule->GetTotalNumberAOs(); |
3585 | + int usedMONumber = this->molecule->GetTotalNumberValenceElectrons()/2 | |
3586 | + +Parameters::GetInstance()->GetActiveVirCIS(); | |
3583 | 3587 | double** tmpMatrix=NULL; |
3584 | 3588 | try{ |
3585 | 3589 | MallocerFreer::GetInstance()->Malloc<double>(&tmpMatrix,totalAONumber,totalAONumber); |
@@ -3589,13 +3593,13 @@ void Cndo2::CalcOverlapMOsWithAnotherElectronicStructure(double** overlapMOs, | ||
3589 | 3593 | double beta=0.0; |
3590 | 3594 | MolDS_wrappers::Blas::GetInstance()->Dgemm(isColumnMajorOverlapAOs, |
3591 | 3595 | isColumnMajorRhsFock, |
3592 | - totalAONumber,totalAONumber,totalAONumber, | |
3596 | + totalAONumber,usedMONumber,totalAONumber, | |
3593 | 3597 | alpha, |
3594 | 3598 | overlapAOs, |
3595 | 3599 | rhsFockMatrix, |
3596 | 3600 | beta, |
3597 | 3601 | tmpMatrix); |
3598 | - MolDS_wrappers::Blas::GetInstance()->Dgemm(totalAONumber,totalAONumber,totalAONumber, | |
3602 | + MolDS_wrappers::Blas::GetInstance()->Dgemm(usedMONumber,totalAONumber,totalAONumber, | |
3599 | 3603 | lhsFockMatrix, |
3600 | 3604 | tmpMatrix, |
3601 | 3605 | overlapMOs); |
@@ -3608,6 +3612,33 @@ void Cndo2::CalcOverlapMOsWithAnotherElectronicStructure(double** overlapMOs, | ||
3608 | 3612 | MallocerFreer::GetInstance()->Free<double>(&tmpMatrix,totalAONumber,totalAONumber); |
3609 | 3613 | } |
3610 | 3614 | |
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 | + | |
3611 | 3642 | // calculate OverlapAOs matrix. E.g. S_{\mu\nu} in (3.74) in J. A. Pople book. |
3612 | 3643 | void Cndo2::CalcOverlapAOs(double** overlapAOs, const Molecule& molecule) const{ |
3613 | 3644 | int totalAONumber = molecule.GetTotalNumberAOs(); |
@@ -46,6 +46,11 @@ public: | ||
46 | 46 | void CalcOverlapMOsWithAnotherElectronicStructure(double** overlapMOs, |
47 | 47 | double const* const* overlapAOs, |
48 | 48 | 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; | |
49 | 54 | MolDS_base::TheoryType GetTheoryType() const; |
50 | 55 | protected: |
51 | 56 | std::string errorMessageAtomA; |
@@ -74,6 +79,7 @@ protected: | ||
74 | 79 | std::string errorMessageCalcFrequenciesNormalModesBadTheory; |
75 | 80 | std::string errorMessageFromState; |
76 | 81 | std::string errorMessageToState; |
82 | + std::string errorMessageNonExcitedStates; | |
77 | 83 | std::string messageSCFMetConvergence; |
78 | 84 | std::string messageStartSCF; |
79 | 85 | std::string messageDoneSCF; |
@@ -82,6 +82,8 @@ void Indo::SetMessages(){ | ||
82 | 82 | = "Error in indo::Indo::GetElectronicEnergy: excitedEnergies is NULL\n"; |
83 | 83 | this->errorMessageCalcFrequenciesNormalModesBadTheory |
84 | 84 | = "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"; | |
85 | 87 | this->messageSCFMetConvergence = "\n\n\n\t\tINDO-SCF met convergence criterion(^^b\n\n\n"; |
86 | 88 | this->messageStartSCF = "********** START: INDO-SCF **********\n"; |
87 | 89 | this->messageDoneSCF = "********** DONE: INDO-SCF **********\n\n\n"; |
@@ -105,13 +105,14 @@ void NASCO::DoNASCO(Molecule& molecule){ | ||
105 | 105 | molecule.OutputXyzCOC(); |
106 | 106 | molecule.OutputMomenta(); |
107 | 107 | |
108 | - // malloc ovelap AOs, MOs, ESs between differentMolecules | |
108 | + // malloc ovelap AOs, MOs, Singlet Slater Determinants, and Eigenstates between differentMolecules | |
109 | 109 | double** overlapAOs = NULL; |
110 | 110 | double** overlapMOs = NULL; |
111 | + double** overlapSingletSDs = NULL; | |
111 | 112 | double** overlapESs = NULL; |
112 | 113 | |
113 | 114 | try{ |
114 | - this->MallocOverlapsDifferentMolecules(&overlapAOs, &overlapMOs, &overlapESs, molecule); | |
115 | + this->MallocOverlapsDifferentMolecules(&overlapAOs, &overlapMOs, &overlapSingletSDs, &overlapESs, molecule); | |
115 | 116 | for(int s=0; s<totalSteps; s++){ |
116 | 117 | this->OutputLog(boost::format("%s%d\n") % this->messageStartStepNASCO.c_str() % (s+1) ); |
117 | 118 |
@@ -141,7 +142,7 @@ void NASCO::DoNASCO(Molecule& molecule){ | ||
141 | 142 | // update momenta |
142 | 143 | this->UpdateMomenta(molecule, matrixForce, dt); |
143 | 144 | |
144 | - // calculate overlaps | |
145 | + // calculate overlaps | |
145 | 146 | currentES->CalcOverlapAOsWithAnotherConfiguration(overlapAOs, tmpMolecule); |
146 | 147 | cout << "overlapAOs" << endl; |
147 | 148 | for(int i=0; i<molecule.GetTotalNumberAOs(); i++){ |
@@ -160,6 +161,31 @@ void NASCO::DoNASCO(Molecule& molecule){ | ||
160 | 161 | } |
161 | 162 | cout << endl; |
162 | 163 | } |
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; | |
163 | 189 | |
164 | 190 | // Synchronous molecular configuration and electronic states |
165 | 191 | this->SynchronousMolecularConfiguration(molecule, tmpMolecule); |
@@ -179,10 +205,10 @@ void NASCO::DoNASCO(Molecule& molecule){ | ||
179 | 205 | } |
180 | 206 | } |
181 | 207 | catch(MolDSException ex){ |
182 | - this->FreeOverlapsDifferentMolecules(&overlapAOs, &overlapMOs, &overlapESs, molecule); | |
208 | + this->FreeOverlapsDifferentMolecules(&overlapAOs, &overlapMOs, &overlapSingletSDs, &overlapESs, molecule); | |
183 | 209 | throw ex; |
184 | 210 | } |
185 | - this->FreeOverlapsDifferentMolecules(&overlapAOs, &overlapMOs, &overlapESs, molecule); | |
211 | + this->FreeOverlapsDifferentMolecules(&overlapAOs, &overlapMOs, &overlapSingletSDs, &overlapESs, molecule); | |
186 | 212 | this->OutputLog(this->messageEndNASCO); |
187 | 213 | } |
188 | 214 |
@@ -305,26 +331,36 @@ void NASCO::CheckEnableTheoryType(TheoryType theoryType){ | ||
305 | 331 | |
306 | 332 | void NASCO::MallocOverlapsDifferentMolecules(double*** overlapAOs, |
307 | 333 | double*** overlapMOs, |
334 | + double*** overlapSingletSDs, | |
308 | 335 | double*** overlapESs, |
309 | 336 | const Molecule& molecule) const{ |
310 | 337 | int dimOverlapAOs = molecule.GetTotalNumberAOs(); |
311 | 338 | int dimOverlapMOs = dimOverlapAOs; |
339 | + int dimOverlapSingletSDs = Parameters::GetInstance()->GetActiveOccCIS() | |
340 | + *Parameters::GetInstance()->GetActiveVirCIS() | |
341 | + +1; | |
312 | 342 | 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); | |
316 | 347 | } |
317 | 348 | |
318 | 349 | void NASCO::FreeOverlapsDifferentMolecules(double*** overlapAOs, |
319 | 350 | double*** overlapMOs, |
351 | + double*** overlapSingletSDs, | |
320 | 352 | double*** overlapESs, |
321 | 353 | const MolDS_base::Molecule& molecule) const{ |
322 | 354 | int dimOverlapAOs = molecule.GetTotalNumberAOs(); |
323 | 355 | int dimOverlapMOs = dimOverlapAOs; |
356 | + int dimOverlapSingletSDs = Parameters::GetInstance()->GetActiveOccCIS() | |
357 | + *Parameters::GetInstance()->GetActiveVirCIS() | |
358 | + +1; | |
324 | 359 | 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); | |
328 | 364 | } |
329 | 365 | |
330 | 366 | } |
@@ -58,10 +58,12 @@ private: | ||
58 | 58 | double OutputEnergies(const MolDS_base::ElectronicStructure& electronicStructure, const MolDS_base::Molecule& molecule); |
59 | 59 | void MallocOverlapsDifferentMolecules(double*** overlapAOs, |
60 | 60 | double*** overlapMOs, |
61 | + double*** overlapSingleSDs, | |
61 | 62 | double*** overlapESs, |
62 | 63 | const MolDS_base::Molecule& molecule) const; |
63 | 64 | void FreeOverlapsDifferentMolecules(double*** overlapAOs, |
64 | 65 | double*** overlapMOs, |
66 | + double*** overlapSingleSDs, | |
65 | 67 | double*** overlapESs, |
66 | 68 | const MolDS_base::Molecule& molecule) const; |
67 | 69 | }; |
@@ -32,6 +32,7 @@ | ||
32 | 32 | #include"../base/PrintController.h" |
33 | 33 | #include"../base/MolDSException.h" |
34 | 34 | #include"../base/Uncopyable.h" |
35 | +#include"../wrappers/Blas.h" | |
35 | 36 | #include"../wrappers/Lapack.h" |
36 | 37 | #include"../base/Enums.h" |
37 | 38 | #include"../base/MallocerFreer.h" |
@@ -357,90 +358,40 @@ void BFGS::UpdateHessian(double **matrixHessian, | ||
357 | 358 | double const* vectorOldForce, |
358 | 359 | double const* vectorDisplacement) const{ |
359 | 360 | 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] | |
364 | 363 | try{ |
365 | 364 | MallocerFreer::GetInstance()->Malloc(&P, dimension); |
366 | - MallocerFreer::GetInstance()->Malloc(&PP, dimension, dimension); | |
367 | 365 | MallocerFreer::GetInstance()->Malloc(&HK, dimension); |
368 | - MallocerFreer::GetInstance()->Malloc(&HKKH, dimension,dimension); | |
369 | 366 | double KHK = 0; |
370 | 367 | 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); | |
377 | 372 | |
378 | 373 | // 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); | |
393 | 375 | |
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); | |
404 | 378 | |
405 | 379 | //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); | |
422 | 381 | |
423 | 382 | // 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); | |
432 | 387 | } |
433 | 388 | catch(MolDSException ex){ |
434 | 389 | MallocerFreer::GetInstance()->Free(&P, dimension); |
435 | - MallocerFreer::GetInstance()->Free(&PP, dimension, dimension); | |
436 | 390 | MallocerFreer::GetInstance()->Free(&HK, dimension); |
437 | - MallocerFreer::GetInstance()->Free(&HKKH, dimension,dimension); | |
438 | 391 | throw ex; |
439 | 392 | } |
440 | 393 | MallocerFreer::GetInstance()->Free(&P, dimension); |
441 | - MallocerFreer::GetInstance()->Free(&PP, dimension, dimension); | |
442 | 394 | MallocerFreer::GetInstance()->Free(&HK, dimension); |
443 | - MallocerFreer::GetInstance()->Free(&HKKH, dimension,dimension); | |
444 | 395 | } |
445 | 396 | |
446 | 397 | // Level shift eigenvalues of redandant modes to largeEigenvalue |
@@ -57,6 +57,66 @@ void Blas::DeleteInstance(){ | ||
57 | 57 | blas = NULL; |
58 | 58 | } |
59 | 59 | |
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 | + | |
60 | 120 | // vectorY = matrixA*vectorX |
61 | 121 | // matrixA: m*n-matrix (matrixA[m][n] in row-major (C/C++ style)) |
62 | 122 | // vectorX: n-vector |
@@ -74,7 +134,7 @@ void Blas::Dgemv(int m, int n, | ||
74 | 134 | } |
75 | 135 | |
76 | 136 | // 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 | |
78 | 138 | // vectorX: n-vector |
79 | 139 | // vectorY: m-vector |
80 | 140 | void Blas::Dgemv(bool isColumnMajorMatrixA, |
@@ -99,6 +159,60 @@ void Blas::Dgemv(bool isColumnMajorMatrixA, | ||
99 | 159 | dgemv(&transA, &m, &n, &alpha, a, &lda, vectorX, &incrementX, &beta, vectorY, &incrementY); |
100 | 160 | } |
101 | 161 | |
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 | + | |
102 | 216 | // matrixC = matrixA*matrixB |
103 | 217 | // matrixA: m*k-matrix (matrixA[m][k] in row-major (C/C++ style)) |
104 | 218 | // 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, | ||
115 | 229 | } |
116 | 230 | |
117 | 231 | // 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 | |
120 | 234 | // matrixC: m*n-matrix (matrixC[m][n] in row-major (C/C++ style)) |
121 | 235 | void Blas::Dgemm(bool isColumnMajorMatrixA, |
122 | 236 | bool isColumnMajorMatrixB, |
@@ -24,6 +24,24 @@ class Blas: public MolDS_base::PrintController, private MolDS_base::Uncopyable{ | ||
24 | 24 | public: |
25 | 25 | static Blas* GetInstance(); |
26 | 26 | 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; | |
27 | 45 | void Dgemv(int m, int n, |
28 | 46 | double const* const* matrixA, |
29 | 47 | double const* vectorX, |
@@ -37,6 +55,21 @@ public: | ||
37 | 55 | double beta, |
38 | 56 | double* vectorY, |
39 | 57 | 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; | |
40 | 73 | void Dgemm(int m, int n, int k, |
41 | 74 | double const* const* matrixA, |
42 | 75 | double const* const* matrixB, |
@@ -57,6 +57,70 @@ void Blas::DeleteInstance(){ | ||
57 | 57 | blas = NULL; |
58 | 58 | } |
59 | 59 | |
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 | + | |
60 | 124 | // vectorY = matrixA*vectorX |
61 | 125 | // matrixA: m*n-matrix (matrixA[m][n] in row-major (C/C++ style)) |
62 | 126 | // vectorX: n-vector |
@@ -74,7 +138,7 @@ void Blas::Dgemv(int m, int n, | ||
74 | 138 | } |
75 | 139 | |
76 | 140 | // 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 | |
78 | 142 | // vectorX: n-vector |
79 | 143 | // vectorY: m-vector |
80 | 144 | void Blas::Dgemv(bool isColumnMajorMatrixA, |
@@ -101,6 +165,62 @@ void Blas::Dgemv(bool isColumnMajorMatrixA, | ||
101 | 165 | |
102 | 166 | } |
103 | 167 | |
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 | + | |
104 | 224 | // matrixC = matrixA*matrixB |
105 | 225 | // matrixA: m*k-matrix (matrixA[m][k] in row-major (C/C++ style)) |
106 | 226 | // 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, | ||
117 | 237 | } |
118 | 238 | |
119 | 239 | // 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 | |
122 | 242 | // matrixC: m*n-matrix (matrixC[m][n] in row-major (C/C++ style)) |
123 | 243 | void Blas::Dgemm(bool isColumnMajorMatrixA, |
124 | 244 | bool isColumnMajorMatrixB, |
@@ -320,7 +320,16 @@ int Lapack::Dgetrs(double const* const* matrix, double** b, int size, int nrhs) | ||
320 | 320 | // Argument "matrix" is sizeM*sizeN matrix. |
321 | 321 | // Argument "matrix" will be LU-decomposed. |
322 | 322 | 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{ | |
324 | 333 | double* convertedMatrix = (double*)mkl_malloc( sizeof(double)*sizeM*sizeN, 16 ); |
325 | 334 | for(int i=0; i<sizeM; i++){ |
326 | 335 | for(int j=0; j<sizeN; j++){ |
@@ -334,7 +343,6 @@ int Lapack::Dgetrf(double** matrix, int sizeM, int sizeN) const{ | ||
334 | 343 | } |
335 | 344 | } |
336 | 345 | mkl_free(convertedMatrix); |
337 | - mkl_free(ipiv); | |
338 | 346 | int info = 0; |
339 | 347 | return info; |
340 | 348 | } |
@@ -28,6 +28,7 @@ public: | ||
28 | 28 | int Dsysv(double const* const* matrix, double* b, int size); |
29 | 29 | int Dgetrs(double const* const* matrix, double** b, int size, int nrhs) const; |
30 | 30 | int Dgetrf(double** matrix, int sizeM, int sizeN) const; |
31 | + int Dgetrf(double** matrix, int* ipiv, int sizeM, int sizeN) const; | |
31 | 32 | private: |
32 | 33 | Lapack(); |
33 | 34 | ~Lapack(); |
@@ -319,7 +319,16 @@ int Lapack::Dgetrs(double const* const* matrix, double** b, int size, int nrhs) | ||
319 | 319 | // Argument "matrix" is sizeM*sizeN matrix. |
320 | 320 | // Argument "matrix" will be LU-decomposed. |
321 | 321 | 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{ | |
323 | 332 | double* convertedMatrix = (double*)LAPACKE_malloc( sizeof(double)*sizeM*sizeN ); |
324 | 333 | for(int i=0; i<sizeM; i++){ |
325 | 334 | for(int j=0; j<sizeN; j++){ |
@@ -333,7 +342,6 @@ int Lapack::Dgetrf(double** matrix, int sizeM, int sizeN) const{ | ||
333 | 342 | } |
334 | 343 | } |
335 | 344 | LAPACKE_free(convertedMatrix); |
336 | - LAPACKE_free(ipiv); | |
337 | 345 | int info = 0; |
338 | 346 | return info; |
339 | 347 | } |
@@ -30,8 +30,10 @@ | ||
30 | 30 | #include"../base/PrintController.h" |
31 | 31 | #include"../base/MolDSException.h" |
32 | 32 | #include"../base/Uncopyable.h" |
33 | +#include"../wrappers/Blas.h" | |
33 | 34 | #include"../wrappers/Lapack.h" |
34 | 35 | #include"../base/Enums.h" |
36 | +#include"../base/MathUtilities.h" | |
35 | 37 | #include"../base/MallocerFreer.h" |
36 | 38 | #include"../base/EularAngle.h" |
37 | 39 | #include"../base/Parameters.h" |
@@ -696,6 +698,124 @@ void ZindoS::CalcDiatomicOverlapAOs2ndDerivativeInDiatomicFrame(double** diatomi | ||
696 | 698 | diatomicOverlapAOs2ndDeri[px][px] *= this->overlapAOsCorrectionPi; |
697 | 699 | } |
698 | 700 | |
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 | + | |
699 | 819 | // The order of mol, moJ, moK, moL is consistent with Eq. (9) in [RZ_1973] |
700 | 820 | double ZindoS::GetMolecularIntegralElement(int moI, int moJ, int moK, int moL, |
701 | 821 | const Molecule& molecule, |
@@ -29,6 +29,11 @@ public: | ||
29 | 29 | virtual ~ZindoS(); |
30 | 30 | void DoCIS(); |
31 | 31 | 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; | |
32 | 37 | protected: |
33 | 38 | std::string errorMessageDavidsonNotConverged; |
34 | 39 | std::string errorMessageCalcCISMatrix; |