修订版 | 561dcfe0c70381969cc88a741042400a28722a37 (tree) |
---|---|
时间 | 2011-11-17 08:00:09 |
作者 | Mikiya Fujii <mikiya.fujii@gmai...> |
Commiter | Mikiya Fujii |
Mndo::CalcQVector is implemented. #26396
git-svn-id: https://svn.sourceforge.jp/svnroot/molds/MolDS/trunk@310 1136aad2-a195-0410-b898-f5ea1d11b9d8
@@ -1,7 +1,7 @@ | ||
1 | 1 | CC = icpc |
2 | 2 | LIBS32 = -lmkl_intel -lmkl_intel_thread -lmkl_core -liomp5 -lpthread |
3 | 3 | LIBS64 = -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread |
4 | -CFLAGS = -O3 -openmp -openmp-report2 | |
4 | +CFLAGS = -O2 -openmp -openmp-report2 | |
5 | 5 | EXENAME = MolDS.out |
6 | 6 | DEPFILE = obj/objfile.dep |
7 | 7 |
@@ -755,20 +755,26 @@ void Mndo::CalcActiveSetVariablesQ(vector<MoIndexPair>* nonRedundantQIndeces, | ||
755 | 755 | int numberActiveOcc = Parameters::GetInstance()->GetActiveOccCIS(); |
756 | 756 | int numberActiveVir = Parameters::GetInstance()->GetActiveVirCIS(); |
757 | 757 | for(int i=0; i<numberOcc; i++){ |
758 | + bool isMoICIMO = numberOcc-numberActiveOcc<=i ? true : false; | |
758 | 759 | for(int j=numberOcc; j<numberAOs; j++){ |
759 | - MoIndexPair moIndexPair = {i, j}; | |
760 | + bool isMoJCIMO = j<numberOcc+numberActiveVir ? true : false; | |
761 | + MoIndexPair moIndexPair = {i, j, isMoICIMO, isMoJCIMO}; | |
760 | 762 | nonRedundantQIndeces->push_back(moIndexPair); |
761 | 763 | } |
762 | 764 | } |
763 | 765 | for(int i=numberOcc-numberActiveOcc; i<numberOcc; i++){ |
766 | + bool isMoICIMO = true; | |
764 | 767 | for(int j=i; j<numberOcc; j++){ |
765 | - MoIndexPair moIndexPair = {i, j}; | |
768 | + bool isMoJCIMO = true; | |
769 | + MoIndexPair moIndexPair = {i, j, isMoICIMO, isMoJCIMO}; | |
766 | 770 | redundantQIndeces->push_back(moIndexPair); |
767 | 771 | } |
768 | 772 | } |
769 | 773 | for(int i=numberOcc; i<numberOcc+numberActiveVir; i++){ |
774 | + bool isMoICIMO = true; | |
770 | 775 | for(int j=i; j<numberOcc+numberActiveVir; j++){ |
771 | - MoIndexPair moIndexPair = {i, j}; | |
776 | + bool isMoJCIMO = true; | |
777 | + MoIndexPair moIndexPair = {i, j, isMoICIMO, isMoJCIMO}; | |
772 | 778 | redundantQIndeces->push_back(moIndexPair); |
773 | 779 | } |
774 | 780 | } |
@@ -1035,9 +1041,196 @@ void Mndo::CalcDeltaVector(double* delta, int elecState){ | ||
1035 | 1041 | } |
1036 | 1042 | } |
1037 | 1043 | |
1044 | +// see (18) in [PT_1977] | |
1045 | +double Mndo::GetSmallQElement(int moI, | |
1046 | + int moP, | |
1047 | + double** xiOcc, | |
1048 | + double** xiVir, | |
1049 | + double** eta){ | |
1050 | + double value = 0.0; | |
1051 | + int numberOcc = this->molecule->GetTotalNumberValenceElectrons()/2; | |
1052 | + bool isMoPOcc = moP<numberOcc ? true : false; | |
1053 | + | |
1054 | + for(int A=0; A<molecule->GetAtomVect()->size(); A++){ | |
1055 | + Atom* atomA = (*molecule->GetAtomVect())[A]; | |
1056 | + int firstAOIndexA = atomA->GetFirstAOIndex(); | |
1057 | + int numberAOsA = atomA->GetValence().size(); | |
1058 | + | |
1059 | + for(int B=A; B<molecule->GetAtomVect()->size(); B++){ | |
1060 | + Atom* atomB = (*molecule->GetAtomVect())[B]; | |
1061 | + int firstAOIndexB = atomB->GetFirstAOIndex(); | |
1062 | + int numberAOsB = atomB->GetValence().size(); | |
1063 | + | |
1064 | + if(A!=B){ | |
1065 | + for(int mu=firstAOIndexA; mu<firstAOIndexA+numberAOsA; mu++){ | |
1066 | + for(int nu=mu; nu<firstAOIndexA+numberAOsA; nu++){ | |
1067 | + for(int lambda=firstAOIndexB; lambda<firstAOIndexB+numberAOsB; lambda++){ | |
1068 | + for(int sigma=lambda; sigma<firstAOIndexB+numberAOsB; sigma++){ | |
1069 | + double twoElecInt = 0.0; | |
1070 | + twoElecInt = this->twoElecTwoCore[A] | |
1071 | + [B] | |
1072 | + [mu-firstAOIndexA] | |
1073 | + [nu-firstAOIndexA] | |
1074 | + [lambda-firstAOIndexB] | |
1075 | + [sigma-firstAOIndexB]; | |
1076 | + double temp = 0.0; | |
1077 | + if(isMoPOcc){ | |
1078 | + int p = numberOcc - (moP+1); | |
1079 | + temp = 4.0*xiOcc[p][nu]*eta[lambda][sigma] | |
1080 | + -1.0*xiOcc[p][lambda]*eta[nu][sigma] | |
1081 | + -1.0*xiOcc[p][sigma]*eta[nu][lambda]; | |
1082 | + value += twoElecInt*this->fockMatrix[moI][mu]*temp; | |
1083 | + temp = 4.0*xiOcc[p][sigma]*eta[mu][nu] | |
1084 | + -1.0*xiOcc[p][mu]*eta[sigma][nu] | |
1085 | + -1.0*xiOcc[p][nu]*eta[sigma][mu]; | |
1086 | + value += twoElecInt*this->fockMatrix[moI][lambda]*temp; | |
1087 | + } | |
1088 | + else{ | |
1089 | + int p = moP - numberOcc; | |
1090 | + temp = 4.0*xiVir[p][nu]*eta[lambda][sigma] | |
1091 | + -1.0*xiVir[p][lambda]*eta[sigma][nu] | |
1092 | + -1.0*xiVir[p][sigma]*eta[lambda][nu]; | |
1093 | + value += twoElecInt*this->fockMatrix[moI][mu]*temp; | |
1094 | + temp = 4.0*xiVir[p][sigma]*eta[mu][nu] | |
1095 | + -1.0*xiVir[p][mu]*eta[nu][sigma] | |
1096 | + -1.0*xiVir[p][nu]*eta[mu][sigma]; | |
1097 | + value += twoElecInt*this->fockMatrix[moI][lambda]*temp; | |
1098 | + } | |
1099 | + | |
1100 | + if(lambda!=sigma){ | |
1101 | + if(isMoPOcc){ | |
1102 | + int p = numberOcc - (moP+1); | |
1103 | + temp = 4.0*xiOcc[p][nu]*eta[sigma][lambda] | |
1104 | + -1.0*xiOcc[p][sigma]*eta[nu][lambda] | |
1105 | + -1.0*xiOcc[p][lambda]*eta[nu][sigma]; | |
1106 | + value += twoElecInt*this->fockMatrix[moI][mu]*temp; | |
1107 | + temp = 4.0*xiOcc[p][lambda]*eta[mu][nu] | |
1108 | + -1.0*xiOcc[p][mu]*eta[lambda][nu] | |
1109 | + -1.0*xiOcc[p][nu]*eta[lambda][mu]; | |
1110 | + value += twoElecInt*this->fockMatrix[moI][sigma]*temp; | |
1111 | + } | |
1112 | + else{ | |
1113 | + int p = moP - numberOcc; | |
1114 | + temp = 4.0*xiVir[p][nu]*eta[sigma][lambda] | |
1115 | + -1.0*xiVir[p][sigma]*eta[lambda][nu] | |
1116 | + -1.0*xiVir[p][lambda]*eta[sigma][nu]; | |
1117 | + value += twoElecInt*this->fockMatrix[moI][mu]*temp; | |
1118 | + temp = 4.0*xiVir[p][lambda]*eta[mu][nu] | |
1119 | + -1.0*xiVir[p][mu]*eta[nu][lambda] | |
1120 | + -1.0*xiVir[p][nu]*eta[mu][lambda]; | |
1121 | + value += twoElecInt*this->fockMatrix[moI][sigma]*temp; | |
1122 | + } | |
1123 | + } | |
1124 | + | |
1125 | + if(mu!=nu){ | |
1126 | + if(isMoPOcc){ | |
1127 | + int p = numberOcc - (moP+1); | |
1128 | + temp = 4.0*xiOcc[p][mu]*eta[lambda][sigma] | |
1129 | + -1.0*xiOcc[p][lambda]*eta[mu][sigma] | |
1130 | + -1.0*xiOcc[p][sigma]*eta[mu][lambda]; | |
1131 | + value += twoElecInt*this->fockMatrix[moI][nu]*temp; | |
1132 | + temp = 4.0*xiOcc[p][sigma]*eta[nu][mu] | |
1133 | + -1.0*xiOcc[p][nu]*eta[sigma][mu] | |
1134 | + -1.0*xiOcc[p][mu]*eta[sigma][nu]; | |
1135 | + value += twoElecInt*this->fockMatrix[moI][lambda]*temp; | |
1136 | + } | |
1137 | + else{ | |
1138 | + int p = moP - numberOcc; | |
1139 | + temp = 4.0*xiVir[p][mu]*eta[lambda][sigma] | |
1140 | + -1.0*xiVir[p][lambda]*eta[sigma][mu] | |
1141 | + -1.0*xiVir[p][sigma]*eta[lambda][mu]; | |
1142 | + value += twoElecInt*this->fockMatrix[moI][nu]*temp; | |
1143 | + temp = 4.0*xiVir[p][sigma]*eta[nu][mu] | |
1144 | + -1.0*xiVir[p][nu]*eta[mu][sigma] | |
1145 | + -1.0*xiVir[p][mu]*eta[nu][sigma]; | |
1146 | + value += twoElecInt*this->fockMatrix[moI][lambda]*temp; | |
1147 | + } | |
1148 | + | |
1149 | + if(mu!=nu && lambda!=sigma){ | |
1150 | + if(isMoPOcc){ | |
1151 | + int p = numberOcc - (moP+1); | |
1152 | + temp = 4.0*xiOcc[p][mu]*eta[sigma][lambda] | |
1153 | + -1.0*xiOcc[p][sigma]*eta[mu][lambda] | |
1154 | + -1.0*xiOcc[p][lambda]*eta[mu][sigma]; | |
1155 | + value += twoElecInt*this->fockMatrix[moI][nu]*temp; | |
1156 | + temp = 4.0*xiOcc[p][lambda]*eta[nu][mu] | |
1157 | + -1.0*xiOcc[p][nu]*eta[lambda][mu] | |
1158 | + -1.0*xiOcc[p][mu]*eta[lambda][nu]; | |
1159 | + value += twoElecInt*this->fockMatrix[moI][sigma]*temp; | |
1160 | + } | |
1161 | + else{ | |
1162 | + int p = moP - numberOcc; | |
1163 | + temp = 4.0*xiVir[p][mu]*eta[sigma][lambda] | |
1164 | + -1.0*xiVir[p][sigma]*eta[lambda][mu] | |
1165 | + -1.0*xiVir[p][lambda]*eta[sigma][mu]; | |
1166 | + value += twoElecInt*this->fockMatrix[moI][nu]*temp; | |
1167 | + temp = 4.0*xiVir[p][lambda]*eta[nu][mu] | |
1168 | + -1.0*xiVir[p][nu]*eta[mu][lambda] | |
1169 | + -1.0*xiVir[p][mu]*eta[nu][lambda]; | |
1170 | + value += twoElecInt*this->fockMatrix[moI][sigma]*temp; | |
1171 | + } | |
1172 | + } | |
1173 | + | |
1174 | + } | |
1175 | + } | |
1176 | + } | |
1177 | + } | |
1178 | + } | |
1179 | + } | |
1180 | + else{ | |
1181 | + for(int mu=firstAOIndexA; mu<firstAOIndexA+numberAOsA; mu++){ | |
1182 | + for(int nu=firstAOIndexA; nu<firstAOIndexA+numberAOsA; nu++){ | |
1183 | + for(int lambda=firstAOIndexB; lambda<firstAOIndexB+numberAOsB; lambda++){ | |
1184 | + for(int sigma=firstAOIndexB; sigma<firstAOIndexB+numberAOsB; sigma++){ | |
1185 | + double twoElecInt = 0.0; | |
1186 | + if(mu==nu && lambda==sigma){ | |
1187 | + OrbitalType orbitalMu = atomA->GetValence()[mu-firstAOIndexA]; | |
1188 | + OrbitalType orbitalLambda = atomB->GetValence()[lambda-firstAOIndexB]; | |
1189 | + twoElecInt = this->GetCoulombInt(orbitalMu, | |
1190 | + orbitalLambda, | |
1191 | + atomA); | |
1192 | + } | |
1193 | + else if((mu==lambda && nu==sigma) || (nu==lambda && mu==sigma) ){ | |
1194 | + OrbitalType orbitalMu = atomA->GetValence()[mu-firstAOIndexA]; | |
1195 | + OrbitalType orbitalNu = atomA->GetValence()[nu-firstAOIndexA]; | |
1196 | + twoElecInt = this->GetExchangeInt(orbitalMu, | |
1197 | + orbitalNu, | |
1198 | + atomA); | |
1199 | + } | |
1200 | + else{ | |
1201 | + twoElecInt = 0.0; | |
1202 | + } | |
1203 | + | |
1204 | + double temp = 0.0; | |
1205 | + if(isMoPOcc){ | |
1206 | + int p = numberOcc - (moP+1); | |
1207 | + temp = 4.0*xiOcc[p][nu]*eta[lambda][sigma] | |
1208 | + -1.0*xiOcc[p][lambda]*eta[nu][sigma] | |
1209 | + -1.0*xiOcc[p][sigma]*eta[nu][lambda]; | |
1210 | + } | |
1211 | + else{ | |
1212 | + int p = moP - numberOcc; | |
1213 | + temp = 4.0*xiVir[p][nu]*eta[lambda][sigma] | |
1214 | + -1.0*xiVir[p][lambda]*eta[sigma][nu] | |
1215 | + -1.0*xiVir[p][sigma]*eta[lambda][nu]; | |
1216 | + } | |
1217 | + value += twoElecInt*this->fockMatrix[moI][mu]*temp; | |
1218 | + } | |
1219 | + } | |
1220 | + } | |
1221 | + } | |
1222 | + } | |
1223 | + } | |
1224 | + } | |
1225 | + return value; | |
1226 | +} | |
1227 | + | |
1038 | 1228 | // see (20) - (23) in [PT_1997] |
1039 | 1229 | void Mndo::CalcQVector(double* q, |
1040 | 1230 | double* delta, |
1231 | + double** xiOcc, | |
1232 | + double** xiVir, | |
1233 | + double** eta, | |
1041 | 1234 | int elecState, |
1042 | 1235 | vector<MoIndexPair> nonRedundantQIndeces, |
1043 | 1236 | vector<MoIndexPair> redundantQIndeces){ |
@@ -1045,10 +1238,54 @@ void Mndo::CalcQVector(double* q, | ||
1045 | 1238 | q, |
1046 | 1239 | nonRedundantQIndeces.size()+redundantQIndeces.size()); |
1047 | 1240 | |
1048 | - // ToDo: implement CalcQVector | |
1049 | - stringstream ss; | |
1050 | - ss << "Error: Mndo::CalcQVector is not implemented."; | |
1051 | - throw MolDSException(ss.str()); | |
1241 | + int numberOcc = this->molecule->GetTotalNumberValenceElectrons()/2; | |
1242 | + int numberActiveOcc = Parameters::GetInstance()->GetActiveOccCIS(); | |
1243 | + int moI = 0; | |
1244 | + int moJ = 0; | |
1245 | + bool isMoICIMO = false; | |
1246 | + bool isMoJCIMO = false; | |
1247 | + for(int i=0; i<nonRedundantQIndeces.size(); i++){ | |
1248 | + moI = nonRedundantQIndeces[i].moI; | |
1249 | + moJ = nonRedundantQIndeces[i].moJ; | |
1250 | + isMoICIMO = nonRedundantQIndeces[i].isMoICIMO; | |
1251 | + isMoJCIMO = nonRedundantQIndeces[i].isMoJCIMO; | |
1252 | + if(!isMoICIMO && isMoJCIMO){ | |
1253 | + q[i] = this->GetSmallQElement(moI, moJ, xiOcc, xiVir, eta); | |
1254 | + } | |
1255 | + else if(isMoICIMO && !isMoJCIMO){ | |
1256 | + q[i] = -1.0*this->GetSmallQElement(moJ, moI, xiOcc, xiVir, eta); | |
1257 | + } | |
1258 | + else if(isMoICIMO && isMoJCIMO){ | |
1259 | + q[i] = this->GetSmallQElement(moI, moJ, xiOcc, xiVir, eta) | |
1260 | + -this->GetSmallQElement(moJ, moI, xiOcc, xiVir, eta); | |
1261 | + } | |
1262 | + else{ | |
1263 | + q[i] = 0.0; | |
1264 | + } | |
1265 | + } | |
1266 | + for(int i=0; i<redundantQIndeces.size(); i++){ | |
1267 | + int r = nonRedundantQIndeces.size() + i; | |
1268 | + moI = redundantQIndeces[i].moI; | |
1269 | + moJ = redundantQIndeces[i].moJ; | |
1270 | + if(moI == moJ){ | |
1271 | + int rr = moI - (numberOcc-numberActiveOcc); | |
1272 | + q[r] = delta[rr]; | |
1273 | + } | |
1274 | + else{ | |
1275 | + q[r] = this->GetSmallQElement(moI, moJ, xiOcc, xiVir, eta) | |
1276 | + -this->GetSmallQElement(moJ, moI, xiOcc, xiVir, eta); | |
1277 | + | |
1278 | + } | |
1279 | + } | |
1280 | + /* | |
1281 | + for(int i=0; i<nonRedundantQIndeces.size(); i++){ | |
1282 | + printf("q[%d] = %e\n",i,q[i]); | |
1283 | + } | |
1284 | + for(int i=0; i<redundantQIndeces.size(); i++){ | |
1285 | + int r = nonRedundantQIndeces.size() + i; | |
1286 | + printf("q[%d] = %e\n",r,q[r]); | |
1287 | + } | |
1288 | + */ | |
1052 | 1289 | } |
1053 | 1290 | |
1054 | 1291 | // see (43) and (45) in [PT_1996]. |
@@ -1246,12 +1483,19 @@ void Mndo::CalcZMatrixForce(vector<int> elecStates){ | ||
1246 | 1483 | this->CalcDeltaVector(delta, elecState); |
1247 | 1484 | this->CalcXiMatrices(xiOcc, xiVir, elecState, transposedFockMatrix); |
1248 | 1485 | this->CalcEtaMatrix(eta, elecState, transposedFockMatrix); |
1249 | - this->CalcQVector(q, delta, elecState, nonRedundantQIndeces, redundantQIndeces); | |
1486 | + this->CalcQVector(q, | |
1487 | + delta, | |
1488 | + xiOcc, | |
1489 | + xiVir, | |
1490 | + eta, | |
1491 | + elecState, | |
1492 | + nonRedundantQIndeces, | |
1493 | + redundantQIndeces); | |
1250 | 1494 | this->CaclAuxiliaryVector(y, q, kRDager, nonRedundantQIndeces, redundantQIndeces); |
1251 | 1495 | // solve (54) in [PT_1996] |
1252 | - //MolDS_mkl_wrapper::LapackWrapper::GetInstance()->Dsysv(kNR, | |
1253 | - // y, | |
1254 | - // nonRedundantQIndeces.size()); | |
1496 | + MolDS_mkl_wrapper::LapackWrapper::GetInstance()->Dsysv(kNR, | |
1497 | + y, | |
1498 | + nonRedundantQIndeces.size()); | |
1255 | 1499 | |
1256 | 1500 | // calculate each element of Z matrix. |
1257 | 1501 | for(int mu=0; mu<numberAOs; mu++){ |
@@ -1298,7 +1542,7 @@ void Mndo::CalcZMatrixForce(vector<int> elecStates){ | ||
1298 | 1542 | |
1299 | 1543 | bool Mndo::RequiresExcitedStatesForce(vector<int> elecStates){ |
1300 | 1544 | bool requires = true; |
1301 | - if(elecStates.size()==0 && elecStates[0]==0){ | |
1545 | + if(elecStates.size()==1 && elecStates[0]==0){ | |
1302 | 1546 | requires = false; |
1303 | 1547 | } |
1304 | 1548 | return requires; |
@@ -84,7 +84,7 @@ private: | ||
84 | 84 | std::string errorMessageMultipoleB; |
85 | 85 | std::string messageHeatsFormation; |
86 | 86 | std::string messageHeatsFormationTitle; |
87 | - struct MoIndexPair{int moI; int moJ;}; | |
87 | + struct MoIndexPair{int moI; int moJ; bool isMoICIMO; bool isMoJCIMO;}; | |
88 | 88 | double*** zMatrixForce; |
89 | 89 | int zMatrixForceElecStatesNum; |
90 | 90 | double heatsFormation; |
@@ -118,8 +118,16 @@ private: | ||
118 | 118 | int sizeQNR, |
119 | 119 | int sizeQR); |
120 | 120 | void CalcDeltaVector(double* delta, int elecState); |
121 | + double GetSmallQElement(int moI, | |
122 | + int moP, | |
123 | + double**xiOcc, | |
124 | + double** xiVir, | |
125 | + double** eta); | |
121 | 126 | void CalcQVector(double* q, |
122 | 127 | double* delta, |
128 | + double** xiOcc, | |
129 | + double** xiVir, | |
130 | + double** eta, | |
123 | 131 | int elecState, |
124 | 132 | std::vector<MoIndexPair> nonRedundantQIndeces, |
125 | 133 | std::vector<MoIndexPair> redundantQIndeces); |