• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

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

Commit MetaInfo

Revision3a08df6186f3109360990c656bc4ae8dbb30aa32 (tree)
Time2013-05-24 18:52:00
AuthorMikiya Fujii <mikiya.fujii@gmai...>
CommiterMikiya Fujii

Log Message

Cache of two electron integral, that is Nishimoto-Mataga, is implemented. #31428

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

Change Summary

Incremental Difference

--- a/src/mndo/Mndo.cpp
+++ b/src/mndo/Mndo.cpp
@@ -82,7 +82,7 @@ Mndo::~Mndo(){
8282 }
8383
8484 void Mndo::SetMolecule(Molecule* molecule){
85- Cndo2::SetMolecule(molecule);
85+ ZindoS::SetMolecule(molecule);
8686 MallocerFreer::GetInstance()->Malloc<double>(&this->twoElecTwoCore,
8787 molecule->GetNumberAtoms(),
8888 molecule->GetNumberAtoms(),
--- a/src/zindo/ZindoS.cpp
+++ b/src/zindo/ZindoS.cpp
@@ -73,6 +73,7 @@ ZindoS::ZindoS() : MolDS_cndo::Cndo2(){
7373 this->etaMatrixForce = NULL;
7474
7575 //private variables
76+ this->nishimotoMatagaMatrix = NULL;
7677 this->matrixForceElecStatesNum = 0;
7778 this->nishimotoMatagaParamA = 1.2;
7879 this->nishimotoMatagaParamB = 2.4;
@@ -82,6 +83,13 @@ ZindoS::ZindoS() : MolDS_cndo::Cndo2(){
8283 }
8384
8485 ZindoS::~ZindoS(){
86+ if(this->theory==ZINDOS){
87+ MallocerFreer::GetInstance()->Free<double>(&this->nishimotoMatagaMatrix,
88+ this->molecule->GetNumberAtoms(),
89+ OrbitalType_end,
90+ this->molecule->GetNumberAtoms(),
91+ OrbitalType_end);
92+ }
8593 MallocerFreer::GetInstance()->Free<double>(&this->matrixCIS,
8694 this->matrixCISdimension,
8795 this->matrixCISdimension);
@@ -119,6 +127,17 @@ ZindoS::~ZindoS(){
119127 //this->OutputLog("ZindoS deleted\n");
120128 }
121129
130+void ZindoS::SetMolecule(Molecule* molecule){
131+ Cndo2::SetMolecule(molecule);
132+ if(this->theory==ZINDOS){
133+ MallocerFreer::GetInstance()->Malloc<double>(&this->nishimotoMatagaMatrix,
134+ this->molecule->GetNumberAtoms(),
135+ OrbitalType_end,
136+ this->molecule->GetNumberAtoms(),
137+ OrbitalType_end);
138+ }
139+}
140+
122141 void ZindoS::SetMessages(){
123142 this->errorMessageSCFNotConverged
124143 = "Error in zindo::ZindoS::DoSCF: SCF did not met convergence criterion. maxIterationsSCF=";
@@ -242,14 +261,10 @@ double ZindoS::GetFockDiagElement(const Atom& atomA,
242261 sigma = i + atomB.GetFirstAOIndex();
243262 orbitalSigma = atomB.GetValence(i);
244263 temp += orbitalElectronPopulationDiagPart[sigma]
245- *this->GetNishimotoMatagaTwoEleInt(atomA,
246- orbitalMu,
247- atomB,
248- orbitalSigma,
249- rAB);
264+ *this->nishimotoMatagaMatrix[indexAtomA][orbitalMu][B][orbitalSigma];
250265 }
251266 temp -= atomB.GetCoreCharge()
252- *this->GetNishimotoMatagaTwoEleInt(atomA, s, atomB, s, rAB);
267+ *this->nishimotoMatagaMatrix[indexAtomA][s][B][s];
253268 }
254269 }
255270 value += temp;
@@ -290,7 +305,7 @@ double ZindoS::GetFockOffDiagElement(const Atom& atomA,
290305 else{
291306 value = bondParameter*overlapAOs[mu][nu];
292307 value -= 0.5*orbitalElectronPopulation[mu][nu]
293- *this->GetNishimotoMatagaTwoEleInt(atomA, orbitalMu, atomB, orbitalNu);
308+ *this->nishimotoMatagaMatrix[indexAtomA][orbitalMu][indexAtomB][orbitalNu];
294309 }
295310 }
296311 return value;
@@ -564,6 +579,11 @@ double ZindoS::GetExchangeInt(OrbitalType orbital1, OrbitalType orbital2, const
564579 return value;
565580 }
566581
582+void ZindoS::CalcTwoElecTwoCore(double****** twoElecTwoCore,
583+ const Molecule& molecule) const{
584+ this->CalcNishimotoMatagaMatrix(this->nishimotoMatagaMatrix, molecule);
585+}
586+
567587 // ref. [MN_1957] and (5a) in [AEZ_1986]
568588 double ZindoS::GetNishimotoMatagaTwoEleInt(const Atom& atomA, OrbitalType orbitalA,
569589 const Atom& atomB, OrbitalType orbitalB) const{
@@ -727,6 +747,9 @@ void ZindoS::CalcNishimotoMatagaMatrix(double**** nishimotoMatagaMatrix, const M
727747 atomB,
728748 orbitalNu,
729749 rAB);
750+ if(A!=B){
751+ nishimotoMatagaMatrix[B][orbitalNu][A][orbitalMu] = nishimotoMatagaMatrix[A][orbitalMu][B][orbitalNu];
752+ }
730753 }
731754 }
732755 }
@@ -944,10 +967,7 @@ double ZindoS::GetMolecularIntegralElement(int moI, int moJ, int moK, int moL,
944967 OrbitalType orbitalNu = atomB.GetValence(nu-firstAOIndexB);
945968
946969 if(A<B){
947- gamma = this->GetNishimotoMatagaTwoEleInt(atomA,
948- orbitalMu,
949- atomB,
950- orbitalNu);
970+ gamma = this->nishimotoMatagaMatrix[A][orbitalMu][B][orbitalNu];
951971 value += gamma
952972 *fockMatrix[moI][mu]
953973 *fockMatrix[moJ][mu]
@@ -2258,68 +2278,56 @@ void ZindoS::CalcCISMatrix(double** matrixCIS) const{
22582278 this->OutputLog(this->messageStartCalcCISMatrix);
22592279 double ompStartTime = omp_get_wtime();
22602280
2261- int totalNumberAtoms = this->molecule->GetNumberAtoms();
2262- double**** nishimotoMatagaMatrix=NULL;
2263- try{
2264- MallocerFreer::GetInstance()->Malloc<double>(&nishimotoMatagaMatrix, totalNumberAtoms, OrbitalType_end, totalNumberAtoms, OrbitalType_end);
2265- this->CalcNishimotoMatagaMatrix(nishimotoMatagaMatrix, *this->molecule);
2266-
2267- stringstream ompErrors;
2281+ stringstream ompErrors;
22682282 #pragma omp parallel for schedule(auto)
2269- for(int k=0; k<this->matrixCISdimension; k++){
2270- try{
2271- // single excitation from I-th (occupied)MO to A-th (virtual)MO
2272- int moI = this->GetActiveOccIndex(*this->molecule, k);
2273- int moA = this->GetActiveVirIndex(*this->molecule, k);
2274-
2275- for(int l=k; l<this->matrixCISdimension; l++){
2276- // single excitation from J-th (occupied)MO to B-th (virtual)MO
2277- int moJ = this->GetActiveOccIndex(*this->molecule, l);
2278- int moB = this->GetActiveVirIndex(*this->molecule, l);
2279-
2280- // Fast algorithm, but this is not easy to read. Slow algorithm is also written below.
2281- if(k<l){
2282- // Off diagonal term (right upper)
2283- matrixCIS[k][l] = this->GetCISOffDiagElement(nishimotoMatagaMatrix, *this->molecule, this->fockMatrix, moI, moA, moJ, moB);
2284- }
2285- else if(k==l){
2286- // Diagonal term
2287- matrixCIS[k][l] = this->GetCISDiagElement(energiesMO, nishimotoMatagaMatrix, *this->molecule, this->fockMatrix, moI, moA);
2288- }
2289- // End of the fast algorith.
2290-
2291- /*// Slow algorith, but this is easy to read. Fast altorithm is also written above.
2292- double value=0.0;
2293- value = 2.0*this->GetMolecularIntegralElement(moA, moI, moJ, moB,
2294- *this->molecule,
2295- this->fockMatrix,
2296- NULL)
2297- -this->GetMolecularIntegralElement(moA, moB, moI, moJ,
2298- *this->molecule,
2299- this->fockMatrix,
2300- NULL);
2301- if(k==l){
2302- value += this->energiesMO[moA] - this->energiesMO[moI];
2303- }
2304- matrixCIS[k][l] = value;
2305- // End of the slow algorith. */
2283+ for(int k=0; k<this->matrixCISdimension; k++){
2284+ try{
2285+ // single excitation from I-th (occupied)MO to A-th (virtual)MO
2286+ int moI = this->GetActiveOccIndex(*this->molecule, k);
2287+ int moA = this->GetActiveVirIndex(*this->molecule, k);
2288+
2289+ for(int l=k; l<this->matrixCISdimension; l++){
2290+ // single excitation from J-th (occupied)MO to B-th (virtual)MO
2291+ int moJ = this->GetActiveOccIndex(*this->molecule, l);
2292+ int moB = this->GetActiveVirIndex(*this->molecule, l);
2293+
2294+ // Fast algorithm, but this is not easy to read. Slow algorithm is also written below.
2295+ if(k<l){
2296+ // Off diagonal term (right upper)
2297+ matrixCIS[k][l] = this->GetCISOffDiagElement(this->nishimotoMatagaMatrix, *this->molecule, this->fockMatrix, moI, moA, moJ, moB);
23062298 }
2299+ else if(k==l){
2300+ // Diagonal term
2301+ matrixCIS[k][l] = this->GetCISDiagElement(energiesMO, this->nishimotoMatagaMatrix, *this->molecule, this->fockMatrix, moI, moA);
2302+ }
2303+ // End of the fast algorith.
2304+
2305+ /*// Slow algorith, but this is easy to read. Fast altorithm is also written above.
2306+ double value=0.0;
2307+ value = 2.0*this->GetMolecularIntegralElement(moA, moI, moJ, moB,
2308+ *this->molecule,
2309+ this->fockMatrix,
2310+ NULL)
2311+ -this->GetMolecularIntegralElement(moA, moB, moI, moJ,
2312+ *this->molecule,
2313+ this->fockMatrix,
2314+ NULL);
2315+ if(k==l){
2316+ value += this->energiesMO[moA] - this->energiesMO[moI];
2317+ }
2318+ matrixCIS[k][l] = value;
2319+ // End of the slow algorith. */
23072320 }
2308- catch(MolDSException ex){
2321+ }
2322+ catch(MolDSException ex){
23092323 #pragma omp critical
2310- ompErrors << ex.what() << endl ;
2311- }
2312- } // end of k-loop
2313- // Exception throwing for omp-region
2314- if(!ompErrors.str().empty()){
2315- throw MolDSException(ompErrors.str());
2324+ ompErrors << ex.what() << endl ;
23162325 }
2326+ } // end of k-loop
2327+ // Exception throwing for omp-region
2328+ if(!ompErrors.str().empty()){
2329+ throw MolDSException(ompErrors.str());
23172330 }
2318- catch(MolDSException ex){
2319- MallocerFreer::GetInstance()->Free<double>(&nishimotoMatagaMatrix, totalNumberAtoms, OrbitalType_end, totalNumberAtoms, OrbitalType_end);
2320- throw ex;
2321- }
2322- MallocerFreer::GetInstance()->Free<double>(&nishimotoMatagaMatrix, totalNumberAtoms, OrbitalType_end, totalNumberAtoms, OrbitalType_end);
23232331 double ompEndTime = omp_get_wtime();
23242332 this->OutputLog(boost::format("%s%lf%s\n%s") % this->messageOmpElapsedTimeCalcCISMarix.c_str()
23252333 % (ompEndTime - ompStartTime)
@@ -3028,11 +3036,7 @@ double ZindoS::GetSmallQElement(int moI,
30283036 for(int lambda=firstAOIndexB; lambda<=lastAOIndexB; lambda++){
30293037 const OrbitalType orbitalLambda = atomB.GetValence(lambda-firstAOIndexB);
30303038 double twoElecInt = 0.0;
3031- twoElecInt = this->GetNishimotoMatagaTwoEleInt(atomA,
3032- orbitalMu,
3033- atomB,
3034- orbitalLambda,
3035- rAB);
3039+ twoElecInt = this->nishimotoMatagaMatrix[A][orbitalMu][B][orbitalLambda];
30363040 double temp = 0.0;
30373041 if(isMoPOcc){
30383042 int p = numberOcc - (moP+1);
@@ -3422,11 +3426,7 @@ double ZindoS::GetAuxiliaryKNRKRElement(int moI, int moJ, int moK, int moL) cons
34223426 *this->fockMatrix[moJ][lambda];
34233427 double gamma = 0.0;
34243428 if(A!=B){
3425- gamma = this->GetNishimotoMatagaTwoEleInt(atomA,
3426- orbitalMu,
3427- atomB,
3428- orbitalLambda,
3429- this->molecule->GetDistanceAtoms(atomA, atomB));
3429+ gamma = this->nishimotoMatagaMatrix[A][orbitalMu][B][orbitalLambda];
34303430 }
34313431 else{
34323432 gamma = 0.5*this->GetCoulombInt(orbitalMu, orbitalLambda, atomA);
--- a/src/zindo/ZindoS.h
+++ b/src/zindo/ZindoS.h
@@ -28,6 +28,7 @@ class ZindoS : public MolDS_cndo::Cndo2{
2828 public:
2929 ZindoS();
3030 virtual ~ZindoS();
31+ virtual void SetMolecule(MolDS_base::Molecule* molecule);
3132 void DoCIS();
3233 void OutputCISResults() const;
3334 void CalcOverlapSingletSDsWithAnotherElectronicStructure(double** overlapSingletSDs,
@@ -97,6 +98,8 @@ protected:
9798 virtual double GetExchangeInt(MolDS_base::OrbitalType orbital1,
9899 MolDS_base::OrbitalType orbital2,
99100 const MolDS_base_atoms::Atom& atom) const; // Apendix in [BZ_1979]
101+ virtual void CalcTwoElecTwoCore(double****** twoElecTwoCore,
102+ const MolDS_base::Molecule& molecule) const;
100103 virtual double GetMolecularIntegralElement(int moI,
101104 int moJ,
102105 int moK,
@@ -171,6 +174,7 @@ private:
171174 std::string messageElectronicDipoleMoment;
172175 std::string messageTransitionDipoleMomentsTitle;
173176 std::string messageTransitionDipoleMoment;
177+ double**** nishimotoMatagaMatrix;
174178 int matrixForceElecStatesNum;
175179 double nishimotoMatagaParamA;
176180 double nishimotoMatagaParamB;