• 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

Revision204fdd58bab73315cca63fed089ff5430452f151 (tree)
Time2013-02-05 21:27:01
AuthorKatsuhiko Nishimra <ktns.87@gmai...>
CommiterKatsuhiko Nishimra

Log Message

Merge trunk into branch automake. #28588

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

Change Summary

Incremental Difference

--- a/doc/README.txt
+++ b/doc/README.txt
@@ -1,6 +1,7 @@
11 //************************************************************************//
22 // Copyright (C) 2011-2012 Mikiya Fujii //
33 // Copyright (C) 2012-2012 Katsuhiko Nishimra //
4+// Copyright (C) 2013-2013 Michihiro Okuyama //
45 // //
56 // This file is part of MolDS. //
67 // //
@@ -66,6 +67,9 @@ COMPILE(using GNUmake):
6667
6768 For both case, the compile succeeded if you could fine "MolDS.out" in the "src" directory.
6869 Type "$ make clean" when you wanna clean the compilation.
70+ If you want to compile MolDS in debug-mode, -g and -DMOLDS_DBG
71+ should be added to CFLAGBASE in the Makefile,
72+ i.e. -O0 -openmp -openmp-report2 -DMKL_INT=intptr_t -g -DMOLDS_DBG
6973
7074 ==============================================================================
7175 CARRY OUT MolDS:
@@ -276,7 +280,7 @@ HOW TO WRITE INPUT:
276280 -options
277281 "davidson", "active_occ", "active_vir", "max_iter", "max_dim", "norm_tol",
278282 "nstates", "exciton_energies", "all_transition_dipole_moments",
279- "mulliken", and "num_print_coefficients" are prepared as options.
283+ "mulliken", "unpaired_electron_population", and "num_print_coefficients" are prepared as options.
280284
281285 "davidson" should be set as "yes" or "no".
282286 The default value of the "davidson" is "yes".
@@ -318,9 +322,16 @@ HOW TO WRITE INPUT:
318322
319323 "mulliken" is a option of mulliken popultaion analysis of the excited state.
320324 When "mulliken x" is included in CIS-directive, the mulliken popultaion of xth excited state is calculated.
321- Mulitiple indication of these mulliken options is possible.
325+ Multiple indication of these mulliken options is possible.
322326 Note that "mulliken 0" is ignored because 0th excited state is the ground state.
323- Default settign of this "mulliken" option is nothing.
327+ Default setting of this "mulliken" option is nothing.
328+
329+ "unpaired_electron_population" is a option of unpaired electron population(UEP) analysis of the excited state.
330+ When "unpaired electron population yes" and "mulliken x" are included in CIS-directive,
331+ the UEP of xth excited state is calculated.
332+ By multiple indication of these mulliken option, the UEP on multiple excited states are possible.
333+ Note that the UEP on ground state is ignored.
334+ Default setting is "unpaired_electron_population" option is nothing.
324335
325336 "num_print_coefficients" is a number of the coefficients of CIS-eigenvector shown in output.
326337 The default value of the "num_print_coefficients" is 1.
@@ -336,6 +347,7 @@ HOW TO WRITE INPUT:
336347 norm_tol 0.000001
337348 mulliken 1
338349 mulliken 2
350+ unpaired_electron_population yes
339351 CIS_END
340352
341353 <Hole Plot>
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -24,6 +24,7 @@
2424 #include<boost/shared_ptr.hpp>
2525 #include<boost/format.hpp>
2626 #include"base/PrintController.h"
27+#include"base/MolDSException.h"
2728 #include"base/Enums.h"
2829 #include"base/EularAngle.h"
2930 #include"base/atoms/Atom.h"
--- a/src/am1/Am1.cpp
+++ b/src/am1/Am1.cpp
@@ -25,6 +25,7 @@
2525 #include<vector>
2626 #include<boost/format.hpp>
2727 #include"../base/PrintController.h"
28+#include"../base/MolDSException.h"
2829 #include"../base/Uncopyable.h"
2930 #include"../base/Enums.h"
3031 #include"../base/EularAngle.h"
--- a/src/am1/Am1D.cpp
+++ b/src/am1/Am1D.cpp
@@ -25,6 +25,7 @@
2525 #include<vector>
2626 #include<boost/format.hpp>
2727 #include"../base/PrintController.h"
28+#include"../base/MolDSException.h"
2829 #include"../base/Uncopyable.h"
2930 #include"../base/Enums.h"
3031 #include"../base/EularAngle.h"
--- a/src/base/Molecule.cpp
+++ b/src/base/Molecule.cpp
@@ -95,6 +95,7 @@ void Molecule::Initialize(){
9595 this->wasCalculatedXyzCOC = false;
9696 this->xyzCOM = NULL;
9797 this->xyzCOC = NULL;
98+ this->atomVect = NULL;
9899 try{
99100 this->atomVect = new vector<Atom*>;
100101 MallocerFreer::GetInstance()->Malloc<double>(&this->xyzCOM, CartesianType_end);
@@ -124,7 +125,9 @@ void Molecule::Finalize(vector<Atom*>** atomVect, double** xyzCOM, double**xyzCO
124125 }
125126
126127 void Molecule::SetMessages(){
127- this->errorMessageGetAtomVectNull = "Error in base::Molecule::GetAtomVect: atomVect is NULL.\n";
128+ this->errorMessageGetAtomNull = "Error in base::Molecule::GetAtom: atomVect is NULL.\n";
129+ this->errorMessageAddAtomNull = "Error in base::Molecule::AddAtom: atomVect is NULL.\n";
130+ this->errorMessageGetNumberAtomsNull = "Error in base::Molecule::GetNumberAtoms: atomVect is NULL.\n";
128131 this->errorMessageGetXyzCOCNull = "Error in base::Molecule::GetXyzCOC: xyzCOC is NULL.\n";
129132 this->errorMessageGetXyzCOMNull = "Error in base::Molecule::GetXyzCOM: xyzCOM is NULL.\n";
130133 this->messageTotalNumberAOs = "\tTotal number of valence AOs: ";
@@ -161,15 +164,17 @@ void Molecule::SetMessages(){
161164 }
162165
163166 void Molecule::AddAtom(Atom* atom){
167+#ifdef MOLDS_DBG
168+ if(this->atomVect==NULL) throw MolDSException(this->errorMessageAddAtomNull);
169+#endif
164170 this->atomVect->push_back(atom);
171+
165172 }
166173
167174 double* Molecule::GetXyzCOM() const{
168- if(this->xyzCOM==NULL){
169- stringstream ss;
170- ss << this->errorMessageGetXyzCOMNull;
171- throw MolDSException(ss.str());
172- }
175+#ifdef MOLDS_DBG
176+ if(this->xyzCOM==NULL) throw MolDSException(this->errorMessageGetXyzCOMNull);
177+#endif
173178 return this->xyzCOM;
174179 }
175180
@@ -181,11 +186,9 @@ double* Molecule::GetXyzCOM(){
181186 }
182187
183188 double* Molecule::GetXyzCOC() const{
184- if(this->xyzCOC==NULL){
185- stringstream ss;
186- ss << this->errorMessageGetXyzCOCNull;
187- throw MolDSException(ss.str());
188- }
189+#ifdef MOLDS_DBG
190+ if(this->xyzCOC==NULL) throw MolDSException(this->errorMessageGetXyzCOCNull);
191+#endif
189192 return this->xyzCOC;
190193 }
191194
--- a/src/base/Molecule.h
+++ b/src/base/Molecule.h
@@ -26,8 +26,18 @@ public:
2626 explicit Molecule(const Molecule& rhs);
2727 Molecule& operator=(const Molecule& rhs);
2828 ~Molecule();
29- int GetNumberAtoms() const{return this->atomVect->size();}
30- MolDS_base_atoms::Atom* GetAtom(int atomIndex) const{return (*this->atomVect)[atomIndex];}
29+ inline int GetNumberAtoms() const{
30+#ifdef MOLDS_DBG
31+ if(this->atomVect==NULL) throw MolDS_base::MolDSException(this->errorMessageGetNumberAtomsNull);
32+#endif
33+ return this->atomVect->size();
34+ }
35+ inline MolDS_base_atoms::Atom* GetAtom(int atomIndex) const{
36+#ifdef MOLDS_DBG
37+ if(this->atomVect==NULL) throw MolDS_base::MolDSException(this->errorMessageGetAtomNull);
38+#endif
39+ return (*this->atomVect)[atomIndex];
40+ }
3141 void AddAtom(MolDS_base_atoms::Atom* atom);
3242 double* GetXyzCOM() const;
3343 double* GetXyzCOM();
@@ -85,7 +95,9 @@ private:
8595 double rotatingAngle,
8696 MolDS_base::EularAngle rotatingEularAngles)const;
8797 void OutputTranslatingConditions(double const* translatingDifference) const;
88- std::string errorMessageGetAtomVectNull;
98+ std::string errorMessageGetAtomNull;
99+ std::string errorMessageAddAtomNull;
100+ std::string errorMessageGetNumberAtomsNull;
89101 std::string errorMessageGetXyzCOCNull;
90102 std::string errorMessageGetXyzCOMNull;
91103 std::string messageTotalNumberAOs;
--- a/src/base/Parameters.cpp
+++ b/src/base/Parameters.cpp
@@ -452,11 +452,9 @@ EularAngle Parameters::GetRotatingEularAngles() const{
452452
453453 // methods for MOPlot
454454 vector<int>* Parameters::GetIndecesMOPlot() const{
455- if(this->indecesMOPlot==NULL){
456- stringstream ss;
457- ss << this->errorMessageGetIndecesMOPlotNull;
458- throw MolDSException(ss.str());
459- }
455+#ifdef MOLDS_DBG
456+ if(this->indecesMOPlot==NULL) throw MolDSException(this->errorMessageGetIndecesMOPlotNull);
457+#endif
460458 return this->indecesMOPlot;
461459 }
462460
@@ -501,11 +499,9 @@ void Parameters::SetFrameLengthMOPlot(double lx, double ly, double lz){
501499
502500 // methods for HolePlot
503501 vector<int>* Parameters::GetElecIndecesHolePlot() const{
504- if(this->elecIndecesHolePlot==NULL){
505- stringstream ss;
506- ss << this->errorMessageGetIndecesHolePlotNull;
507- throw MolDSException(ss.str());
508- }
502+#ifdef MOLDS_DBG
503+ if(this->elecIndecesHolePlot==NULL) throw MolDSException(this->errorMessageGetIndecesHolePlotNull);
504+#endif
509505 return this->elecIndecesHolePlot;
510506 }
511507
@@ -550,11 +546,9 @@ void Parameters::SetFrameLengthHolePlot(double lx, double ly, double lz){
550546
551547 // methods for ParticlePlot
552548 vector<int>* Parameters::GetElecIndecesParticlePlot() const{
553- if(this->elecIndecesParticlePlot==NULL){
554- stringstream ss;
555- ss << this->errorMessageGetIndecesParticlePlotNull;
556- throw MolDSException(ss.str());
557- }
549+#ifdef MOLDS_DBG
550+ if(this->elecIndecesParticlePlot==NULL) throw MolDSException(this->errorMessageGetIndecesParticlePlotNull);
551+#endif
558552 return this->elecIndecesParticlePlot;
559553 }
560554
@@ -687,11 +681,9 @@ void Parameters::SetRequiresAllTransitionDipoleMomentsCIS(bool requiresAllTransi
687681 }
688682
689683 vector<int>* Parameters::GetElectronicStateIndecesMullikenCIS() const{
690- if(this->electronicStateIndecesMullikenCIS==NULL){
691- stringstream ss;
692- ss << this->errorMessageGetElectronicStateIndecesMullikenCISNull;
693- throw MolDSException(ss.str());
694- }
684+#ifdef MOLDS_DBG
685+ if(this->electronicStateIndecesMullikenCIS==NULL) throw MolDSException(this->errorMessageGetElectronicStateIndecesMullikenCISNull);
686+#endif
695687 return this->electronicStateIndecesMullikenCIS;
696688 }
697689
--- a/src/base/atoms/Atom.cpp
+++ b/src/base/atoms/Atom.cpp
@@ -130,7 +130,9 @@ void Atom::SetMessages(){
130130 = "Error in base_atoms::Atom::GetPm3PddgParameterDa: Bad index for parameter Da(daIndex). Only 0, and 1 are permitted.\n";
131131 this->errorMessageDaIndex = "daIndex = ";
132132 this->errorMessageGetXyzCoordinatesNull = "Error in base_atoms::Atom::GetXyz: xyz is NULL\n";
133+ this->errorMessageSetXyzCoordinatesNull = "Error in base_atoms::Atom::SetXyz: xyz is NULL\n";
133134 this->errorMessageGetPxyzMomentaNull = "Error in base_atoms::Atom::GetPxyz: pxyz is NULL\n";
135+ this->errorMessageSetPxyzMomentaNull = "Error in base_atoms::Atom::SetPxyz: pxyz is NULL\n";
134136 }
135137
136138 AtomType Atom::GetAtomType() const{
@@ -146,33 +148,31 @@ double Atom::GetCoreMass() const{
146148 }
147149
148150 double* Atom::GetXyz() const{
149- if(this->xyz==NULL){
150- stringstream ss;
151- ss << this->errorMessageGetXyzCoordinatesNull;
152- throw MolDSException(ss.str());
153- }
151+#ifdef MOLDS_DBG
152+ if(this->xyz==NULL) throw MolDSException(this->errorMessageGetXyzCoordinatesNull);
153+#endif
154154 return this->xyz;
155155 }
156156
157157 double* Atom::GetPxyz() const{
158- if(this->pxyz==NULL){
159- stringstream ss;
160- ss << this->errorMessageGetPxyzMomentaNull;
161- throw MolDSException(ss.str());
162- }
158+#ifdef MOLDS_DBG
159+ if(this->pxyz==NULL) throw MolDSException(this->errorMessageGetPxyzMomentaNull);
160+#endif
163161 return this->pxyz;
164162 }
165163
166164 void Atom::SetXyz(double x, double y, double z) const{
167- xyz[0]= x;
168- xyz[1]= y;
169- xyz[2]= z;
165+#ifdef MOLDS_DBG
166+ if(this->xyz==NULL) throw MolDSException(this->errorMessageSetXyzCoordinatesNull);
167+#endif
168+ xyz[0]= x; xyz[1]= y; xyz[2]= z;
170169 }
171170
172171 void Atom::SetPxyz(double px, double py, double pz) const{
173- pxyz[0]= px;
174- pxyz[1]= py;
175- pxyz[2]= pz;
172+#ifdef MOLDS_DBG
173+ if(this->pxyz==NULL) throw MolDSException(this->errorMessageSetPxyzMomentaNull);
174+#endif
175+ pxyz[0]= px; pxyz[1]= py; pxyz[2]= pz;
176176 }
177177
178178 int Atom::GetValenceSize() const{
--- a/src/base/atoms/Atom.h
+++ b/src/base/atoms/Atom.h
@@ -273,7 +273,9 @@ private:
273273 std::string errorMessageGetNddoHspBadTheory;
274274 std::string errorMessageGetNddoHppBadTheory;
275275 std::string errorMessageGetXyzCoordinatesNull;
276+ std::string errorMessageSetXyzCoordinatesNull;
276277 std::string errorMessageGetPxyzMomentaNull;
278+ std::string errorMessageSetPxyzMomentaNull;
277279 void SetMessages();
278280 double GetRealAngularPartAO(double theta,
279281 double phi,
--- a/src/cndo/Cndo2.cpp
+++ b/src/cndo/Cndo2.cpp
@@ -115,9 +115,9 @@ Cndo2::~Cndo2(){
115115 this->molecule->GetTotalNumberAOs(),
116116 this->molecule->GetTotalNumberAOs());
117117 MallocerFreer::GetInstance()->Free<double>(&this->cartesianMatrix,
118+ CartesianType_end,
118119 this->molecule->GetTotalNumberAOs(),
119- this->molecule->GetTotalNumberAOs(),
120- CartesianType_end);
120+ this->molecule->GetTotalNumberAOs());
121121 int electronicTransitionDipoleMomentsDim = 1;
122122 if(Parameters::GetInstance()->RequiresCIS()){
123123 electronicTransitionDipoleMomentsDim += Parameters::GetInstance()->GetNumberExcitedStatesCIS();
@@ -180,8 +180,8 @@ void Cndo2::SetMessages(){
180180 = "Error in cndo::Cndo2::RotateDiatmicOverlapAOsToSpaceFrame: rotatingMatrix is NULL.\n";
181181 this->errorMessageSetOverlapAOsElementNullDiaMatrix
182182 = "Error in cndo::Cndo2::SetOverlapAOsElement: diatomicOverlapAOs is NULL.\n";
183- this->errorMessageGetElectronicTransitionDipoleMomentBadState
184- = "Error in cndo::Cndo2::GetElectronicTransitionDipoleMoment: Bad eigen state is set. In SCF module, the transition dipole moment of only between ground states can be calculated. Note taht state=0 means the ground state and other state = i means the i-th excited state in below.\n";
183+ this->errorMessageCalcElectronicTransitionDipoleMomentBadState
184+ = "Error in cndo::Cndo2::CalcElectronicTransitionDipoleMoment: Bad eigen state is set. In SCF module, the transition dipole moment of only between ground states can be calculated. Note taht state=0 means the ground state and other state = i means the i-th excited state in below.\n";
185185 this->errorMessageCalcFrequenciesNormalModesBadTheory
186186 = "Error in cndo::Cndo2::CalcFrequenciesNormalModesBadTheory: CNDO2 is not supported for frequency (normal mode) analysis.\n";
187187 this->errorMessageCalcOverlapAOsDifferentConfigurationsDiffAOs
@@ -279,9 +279,9 @@ void Cndo2::SetMolecule(Molecule* molecule){
279279 this->molecule->GetTotalNumberAOs(),
280280 this->molecule->GetTotalNumberAOs());
281281 MallocerFreer::GetInstance()->Malloc<double>(&this->cartesianMatrix,
282+ CartesianType_end,
282283 this->molecule->GetTotalNumberAOs(),
283- this->molecule->GetTotalNumberAOs(),
284- CartesianType_end);
284+ this->molecule->GetTotalNumberAOs());
285285 int electronicTransitionDipoleMomentsDim = 1;
286286 if(Parameters::GetInstance()->RequiresCIS()){
287287 electronicTransitionDipoleMomentsDim += Parameters::GetInstance()->GetNumberExcitedStatesCIS();
@@ -505,12 +505,11 @@ double Cndo2::GetDiatomVdWCorrection2ndDerivative(int indexAtomA,
505505 void Cndo2::DoSCF(bool requiresGuess){
506506 this->OutputLog(this->messageStartSCF);
507507 double ompStartTime = omp_get_wtime();
508-
508+#ifdef MOLDS_DBG
509509 if(this->molecule == NULL){
510- stringstream ss;
511- ss << this->errorMessageMoleculeNotSet;
512- throw MolDSException(ss.str());
510+ throw MolDSException(this->errorMessageMoleculeNotSet);
513511 }
512+#endif
514513
515514 // temporary matrices for scf
516515 double** oldOrbitalElectronPopulation = NULL;
@@ -697,11 +696,11 @@ double Cndo2::GetElectronicEnergy(int elecState) const{
697696 return this->elecSCFEnergy;
698697 }
699698 else{
699+#ifdef MOLDS_DBG
700700 if(this->excitedEnergies == NULL){
701- stringstream ss;
702- ss << this->errorMessageGetElectronicEnergyNULLCISEnergy;
703- throw MolDSException(ss.str());
701+ throw MolDSException(this->errorMessageGetElectronicEnergyNULLCISEnergy);
704702 }
703+#endif
705704 int numberExcitedStates = Parameters::GetInstance()->GetNumberExcitedStatesCIS();
706705 if(numberExcitedStates < elecState){
707706 stringstream ss;
@@ -1655,61 +1654,56 @@ void Cndo2::CalcElectronicDipoleMomentGroundState(double*** electronicTransition
16551654 double const* const* orbitalElectronPopulation,
16561655 double const* const* overlapAOs) const{
16571656 int groundState = 0;
1658- for(int axis=0; axis<CartesianType_end; axis++){
1659- electronicTransitionDipoleMoments[groundState][groundState][axis] = this->GetElectronicTransitionDipoleMoment(
1660- groundState,
1661- groundState,
1662- static_cast<CartesianType>(axis),
1663- NULL,
1664- NULL,
1665- cartesianMatrix,
1666- molecule,
1667- orbitalElectronPopulation,
1668- overlapAOs,
1669- NULL);
1670- }
1657+ this->CalcElectronicTransitionDipoleMoment(electronicTransitionDipoleMoments[groundState][groundState],
1658+ groundState,
1659+ groundState,
1660+ NULL,
1661+ NULL,
1662+ cartesianMatrix,
1663+ molecule,
1664+ orbitalElectronPopulation,
1665+ overlapAOs,
1666+ NULL);
16711667 }
16721668
1673-double Cndo2::GetElectronicTransitionDipoleMoment(int to, int from, CartesianType axis,
1674- double const* const* fockMatrix,
1675- double const* const* matrixCIS,
1676- double const* const* const* cartesianMatrix,
1677- const MolDS_base::Molecule& molecule,
1678- double const* const* orbitalElectronPopulation,
1679- double const* const* overlapAOs,
1680- double const* groundStateDipole) const{
1669+void Cndo2::CalcElectronicTransitionDipoleMoment(double* transitionDipoleMoment,
1670+ int to, int from,
1671+ double const* const* fockMatrix,
1672+ double const* const* matrixCIS,
1673+ double const* const* const* cartesianMatrix,
1674+ const MolDS_base::Molecule& molecule,
1675+ double const* const* orbitalElectronPopulation,
1676+ double const* const* overlapAOs,
1677+ double const* groundStateDipole) const{
16811678 int groundState = 0;
16821679 if(from == groundState && to == groundState){
1683- double value = 0.0;
1680+ double const* centerOfDipole = molecule.GetXyzCOC();
16841681 int totalAONumber = molecule.GetTotalNumberAOs();
1685- stringstream ompErrors;
1686-#pragma omp parallel for reduction(+:value) schedule(auto)
1687- for(int mu=0; mu<totalAONumber; mu++){
1688- try{
1689- double threadValue = 0.0;
1690- for(int nu=0; nu<totalAONumber; nu++){
1691- threadValue -= orbitalElectronPopulation[mu][nu]
1692- *(cartesianMatrix[mu][nu][axis]-molecule.GetXyzCOC()[axis]*overlapAOs[mu][nu]);
1693- }
1694- value += threadValue;
1695- }
1696- catch(MolDSException ex){
1697-#pragma omp critical
1698- ompErrors << ex.what() << endl ;
1699- }
1700- }
1701- // Exception throwing for omp-region
1702- if(!ompErrors.str().empty()){
1703- throw MolDSException(ompErrors.str());
1704- }
1705- return value;
1682+ transitionDipoleMoment[XAxis] = 0.0;
1683+ transitionDipoleMoment[YAxis] = 0.0;
1684+ transitionDipoleMoment[ZAxis] = 0.0;
1685+ transitionDipoleMoment[XAxis] -= MolDS_wrappers::Blas::GetInstance()->Ddot(totalAONumber*totalAONumber,
1686+ &orbitalElectronPopulation[0][0],
1687+ &cartesianMatrix[XAxis][0][0]);
1688+ transitionDipoleMoment[YAxis] -= MolDS_wrappers::Blas::GetInstance()->Ddot(totalAONumber*totalAONumber,
1689+ &orbitalElectronPopulation[0][0],
1690+ &cartesianMatrix[YAxis][0][0]);
1691+ transitionDipoleMoment[ZAxis] -= MolDS_wrappers::Blas::GetInstance()->Ddot(totalAONumber*totalAONumber,
1692+ &orbitalElectronPopulation[0][0],
1693+ &cartesianMatrix[ZAxis][0][0]);
1694+ // set orign of dipole
1695+ double temp = MolDS_wrappers::Blas::GetInstance()->Ddot(totalAONumber*totalAONumber,
1696+ &orbitalElectronPopulation[0][0],
1697+ &overlapAOs[0][0]);
1698+ transitionDipoleMoment[XAxis] += centerOfDipole[XAxis]*temp;
1699+ transitionDipoleMoment[YAxis] += centerOfDipole[YAxis]*temp;
1700+ transitionDipoleMoment[ZAxis] += centerOfDipole[ZAxis]*temp;
17061701 }
17071702 else{
17081703 stringstream ss;
1709- ss << this->errorMessageGetElectronicTransitionDipoleMomentBadState;
1704+ ss << this->errorMessageCalcElectronicTransitionDipoleMomentBadState;
17101705 ss << this->errorMessageFromState << from << endl;
17111706 ss << this->errorMessageToState << to << endl;
1712- ss << this->errorMessageCartesianType << CartesianTypeStr(axis) << endl;
17131707 throw MolDSException(ss.str());
17141708 }
17151709 }
@@ -1735,15 +1729,10 @@ void Cndo2::CalcCartesianMatrixByGTOExpansion(double*** cartesianMatrix,
17351729 for(int b=0; b<atomB.GetValenceSize(); b++){
17361730 int mu = firstAOIndexAtomA + a;
17371731 int nu = firstAOIndexAtomB + b;
1738- for(int i=0; i<CartesianType_end; i++){
1739- double value = this->GetCartesianMatrixElementByGTOExpansion(atomA,
1740- a,
1741- atomB,
1742- b,
1743- static_cast<CartesianType>(i),
1744- stonG);
1745- cartesianMatrix[mu][nu][i] = value;
1746- }
1732+ this->CalcCartesianMatrixElementsByGTOExpansion(cartesianMatrix[XAxis][mu][nu],
1733+ cartesianMatrix[YAxis][mu][nu],
1734+ cartesianMatrix[ZAxis][mu][nu],
1735+ atomA, a, atomB, b, stonG);
17471736 }
17481737 }
17491738
@@ -1758,28 +1747,19 @@ void Cndo2::CalcCartesianMatrixByGTOExpansion(double*** cartesianMatrix,
17581747 if(!ompErrors.str().empty()){
17591748 throw MolDSException(ompErrors.str());
17601749 }
1761- /*
1762- this->OutputLog("cartesian matrix\n");
1763- for(int o=0; o<molecule.GetTotalNumberAOs(); o++){
1764- for(int p=0; p<molecule.GetTotalNumberAOs(); p++){
1765- for(int i=0; i<CartesianType_end; i++){
1766- this->OutputLog(boost::format("%lf\t") % cartesianMatrix[o][p][i]);
1767- }
1768- this->OutputLog("\n");
1769- }
1770- this->OutputLog("\n");
1771- }
1772- this->OutputLog("\n");
1773- */
17741750 }
17751751
17761752 // Calculate elements of Cartesian matrix between atomic orbitals.
17771753 // The analytic Cartesian matrix is calculated with Gaussian expansion technique written in [DY_1977]
1778-double Cndo2::GetCartesianMatrixElementByGTOExpansion(const Atom& atomA, int valenceIndexA,
1754+void Cndo2::CalcCartesianMatrixElementsByGTOExpansion(double& xComponent,
1755+ double& yComponent,
1756+ double& zComponent,
1757+ const Atom& atomA, int valenceIndexA,
17791758 const Atom& atomB, int valenceIndexB,
1780- CartesianType axis,
17811759 STOnGType stonG) const{
1782- double value = 0.0;
1760+ xComponent=0.0;
1761+ yComponent=0.0;
1762+ zComponent=0.0;
17831763 ShellType shellTypeA = atomA.GetValenceShellType();
17841764 ShellType shellTypeB = atomB.GetValenceShellType();
17851765 OrbitalType valenceOrbitalA = atomA.GetValence(valenceIndexA);
@@ -1795,7 +1775,10 @@ double Cndo2::GetCartesianMatrixElementByGTOExpansion(const Atom& atomA, int val
17951775 double Rab = sqrt( pow(atomA.GetXyz()[XAxis]-atomB.GetXyz()[XAxis], 2.0)
17961776 +pow(atomA.GetXyz()[YAxis]-atomB.GetXyz()[YAxis], 2.0)
17971777 +pow(atomA.GetXyz()[ZAxis]-atomB.GetXyz()[ZAxis], 2.0) );
1798- double temp = 0.0;
1778+ double temp = 0.0;
1779+ double tempX = 0.0;
1780+ double tempY = 0.0;
1781+ double tempZ = 0.0;
17991782 for(int i=0; i<=stonG; i++){
18001783 for(int j=0; j<=stonG; j++){
18011784 temp = GTOExpansionSTO::GetInstance()->GetCoefficient(stonG,
@@ -1816,20 +1799,23 @@ double Cndo2::GetCartesianMatrixElementByGTOExpansion(const Atom& atomA, int val
18161799 shellTypeB,
18171800 valenceOrbitalB,
18181801 j);
1819- temp *= this->GetGaussianCartesianMatrix(atomA.GetAtomType(),
1820- valenceOrbitalA,
1821- gaussianExponentA,
1822- atomA.GetXyz(),
1823- atomB.GetAtomType(),
1824- valenceOrbitalB,
1825- gaussianExponentB,
1826- atomB.GetXyz(),
1802+ tempX = this->GetGaussianCartesianMatrix(atomA.GetAtomType(), valenceOrbitalA, gaussianExponentA, atomA.GetXyz(),
1803+ atomB.GetAtomType(), valenceOrbitalB, gaussianExponentB, atomB.GetXyz(),
18271804 Rab,
1828- axis);
1829- value += temp;
1805+ XAxis);
1806+ tempY = this->GetGaussianCartesianMatrix(atomA.GetAtomType(), valenceOrbitalA, gaussianExponentA, atomA.GetXyz(),
1807+ atomB.GetAtomType(), valenceOrbitalB, gaussianExponentB, atomB.GetXyz(),
1808+ Rab,
1809+ YAxis);
1810+ tempZ = this->GetGaussianCartesianMatrix(atomA.GetAtomType(), valenceOrbitalA, gaussianExponentA, atomA.GetXyz(),
1811+ atomB.GetAtomType(), valenceOrbitalB, gaussianExponentB, atomB.GetXyz(),
1812+ Rab,
1813+ ZAxis);
1814+ xComponent += temp*tempX;
1815+ yComponent += temp*tempY;
1816+ zComponent += temp*tempZ;
18301817 }
18311818 }
1832- return value;
18331819 }
18341820
18351821 // calculate gaussian Caretesian integrals.
@@ -3511,11 +3497,11 @@ void Cndo2::CalcOverlapAOsWithAnotherConfiguration(double** overlapAOs,
35113497 ss << this->errorMessageRhs << rhsMolecule->GetNumberAtoms() << endl;
35123498 throw MolDSException(ss.str());
35133499 }
3500+#ifdef MOLDS_DBG
35143501 if(overlapAOs == NULL){
3515- stringstream ss;
3516- ss << this->errorMessageCalcOverlapAOsDifferentConfigurationsOverlapAOsNULL;
3517- throw MolDSException(ss.str());
3502+ throw MolDSException(this->errorMessageCalcOverlapAOsDifferentConfigurationsOverlapAOsNULL);
35183503 }
3504+#endif
35193505
35203506 int totalAONumber = lhsMolecule.GetTotalNumberAOs();
35213507 int totalAtomNumber = lhsMolecule.GetNumberAtoms();
@@ -5036,11 +5022,11 @@ double Cndo2::GetGaussianOverlapAOs1stDerivative(AtomType atomTypeA,
50365022 void Cndo2::CalcRotatingMatrix(double** rotatingMatrix,
50375023 const Atom& atomA,
50385024 const Atom& atomB) const{
5025+#ifdef MOLDS_DBG
50395026 if(rotatingMatrix==NULL){
5040- stringstream ss;
5041- ss << this->errorMessageCalcRotatingMatrixNullRotMatrix;
5042- throw MolDSException(ss.str());
5027+ throw MolDSException(this->errorMessageCalcRotatingMatrixNullRotMatrix);
50435028 }
5029+#endif
50445030 MallocerFreer::GetInstance()->Initialize<double>(rotatingMatrix, OrbitalType_end, OrbitalType_end);
50455031
50465032 double x = atomB.GetXyz()[0] - atomA.GetXyz()[0];
@@ -5338,11 +5324,11 @@ void Cndo2::CalcRotatingMatrix2ndDerivatives(double**** rotMat2ndDerivatives,
53385324 void Cndo2::CalcDiatomicOverlapAOsInDiatomicFrame(double** diatomicOverlapAOs,
53395325 const Atom& atomA,
53405326 const Atom& atomB) const{
5327+#ifdef MOLDS_DBG
53415328 if(diatomicOverlapAOs==NULL){
5342- stringstream ss;
5343- ss << this->errorMessageCalDiaOverlapAOsDiaFrameNullMatrix;
5344- throw MolDSException(ss.str());
5329+ throw MolDSException(this->errorMessageCalDiaOverlapAOsDiaFrameNullMatrix);
53455330 }
5331+#endif
53465332 int na = atomA.GetValenceShellType() + 1;
53475333 int nb = atomB.GetValenceShellType() + 1;
53485334 int m = 0;
@@ -5625,16 +5611,14 @@ void Cndo2::CalcDiatomicOverlapAOs2ndDerivativeInDiatomicFrame(double** diatomic
56255611 // see (B.63) in Pople book.
56265612 void Cndo2::RotateDiatmicOverlapAOsToSpaceFrame(double** diatomicOverlapAOs,
56275613 double const* const* rotatingMatrix) const{
5614+#ifdef MOLDS_DBG
56285615 if(diatomicOverlapAOs==NULL){
5629- stringstream ss;
5630- ss << this->errorMessageRotDiaOverlapAOsToSpaceFrameNullDiaMatrix;
5631- throw MolDSException(ss.str());
5616+ throw MolDSException(this->errorMessageRotDiaOverlapAOsToSpaceFrameNullDiaMatrix);
56325617 }
56335618 if(rotatingMatrix==NULL){
5634- stringstream ss;
5635- ss << this->errorMessageRotDiaOverlapAOsToSpaceFrameNullRotMatrix;
5636- throw MolDSException(ss.str());
5619+ throw MolDSException(this->errorMessageRotDiaOverlapAOsToSpaceFrameNullRotMatrix);
56375620 }
5621+#endif
56385622 double** oldDiatomicOverlapAOs = NULL;
56395623 try{
56405624 MallocerFreer::GetInstance()->Malloc<double>(&oldDiatomicOverlapAOs, OrbitalType_end, OrbitalType_end);
@@ -5679,11 +5663,11 @@ void Cndo2::SetOverlapAOsElement(double** overlapAOs,
56795663 const Atom& atomA,
56805664 const Atom& atomB,
56815665 bool isSymmetricOverlapAOs) const{
5666+#ifdef MOLDS_DBG
56825667 if(diatomicOverlapAOs==NULL){
5683- stringstream ss;
5684- ss << this->errorMessageSetOverlapAOsElementNullDiaMatrix;
5685- throw MolDSException(ss.str());
5668+ throw MolDSException(this->errorMessageSetOverlapAOsElementNullDiaMatrix);
56865669 }
5670+#endif
56875671
56885672 int firstAOIndexAtomA = atomA.GetFirstAOIndex();
56895673 int firstAOIndexAtomB = atomB.GetFirstAOIndex();
--- a/src/cndo/Cndo2.h
+++ b/src/cndo/Cndo2.h
@@ -76,7 +76,7 @@ protected:
7676 std::string errorMessageGetElectronicEnergyEnergyNotCalculated;
7777 std::string errorMessageGetElectronicEnergyNumberCISStates;
7878 std::string errorMessageGetElectronicEnergySetElecState;
79- std::string errorMessageGetElectronicTransitionDipoleMomentBadState;
79+ std::string errorMessageCalcElectronicTransitionDipoleMomentBadState;
8080 std::string errorMessageCalcFrequenciesNormalModesBadTheory;
8181 std::string errorMessageFromState;
8282 std::string errorMessageToState;
@@ -119,14 +119,15 @@ protected:
119119 virtual void CalcSCFProperties();
120120 virtual void CalcCISProperties();
121121 virtual void CalcNormalModes(double** normalModes, double* normalForceConstants, const MolDS_base::Molecule& molecule) const;
122- virtual double GetElectronicTransitionDipoleMoment(int to, int from, MolDS_base::CartesianType axis,
123- double const* const* fockMatrix,
124- double const* const* matrixCIS,
125- double const* const* const* cartesianMatrix,
126- const MolDS_base::Molecule& molecule,
127- double const* const* orbitalElectronPopulation,
128- double const* const* overlapAOs,
129- double const* groundStateDipole) const;
122+ virtual void CalcElectronicTransitionDipoleMoment(double* transitionDipoleMoment,
123+ int to, int from,
124+ double const* const* fockMatrix,
125+ double const* const* matrixCIS,
126+ double const* const* const* cartesianMatrix,
127+ const MolDS_base::Molecule& molecule,
128+ double const* const* orbitalElectronPopulation,
129+ double const* const* overlapAOs,
130+ double const* groundStateDipole) const;
130131 double GetBondingAdjustParameterK(MolDS_base::ShellType shellA,
131132 MolDS_base::ShellType shellB) const;
132133 virtual double GetDiatomCoreRepulsionEnergy(int indexAtomA, int indexAtomB) const;
@@ -343,11 +344,13 @@ private:
343344 void CalcCartesianMatrixByGTOExpansion(double*** cartesianMatrix,
344345 const MolDS_base::Molecule& molecule,
345346 MolDS_base::STOnGType stonG) const;
346- double GetCartesianMatrixElementByGTOExpansion(const MolDS_base_atoms::Atom& atomA,
347+ void CalcCartesianMatrixElementsByGTOExpansion(double& xComponent,
348+ double& yComponent,
349+ double& zComponent,
350+ const MolDS_base_atoms::Atom& atomA,
347351 int valenceIndexA,
348352 const MolDS_base_atoms::Atom& atomB,
349353 int valenceIndexB,
350- MolDS_base::CartesianType axis,
351354 MolDS_base::STOnGType stonG) const;
352355 double GetGaussianCartesianMatrix(MolDS_base::AtomType atomTypeA,
353356 MolDS_base::OrbitalType valenceOrbitalA,
--- a/src/mndo/Mndo.cpp
+++ b/src/mndo/Mndo.cpp
@@ -748,7 +748,39 @@ void Mndo::CalcCISMatrix(double** matrixCIS) const{
748748 if(A!=B){
749749 for(int mu=firstAOIndexA; mu<=lastAOIndexA; mu++){
750750 for(int nu=mu; nu<=lastAOIndexA; nu++){
751+ double tmpMuNu01 = 2.0*fockMatrix[moA][mu]
752+ *fockMatrix[moI][nu];
753+ double tmpMuNu02 = 2.0*fockMatrix[moJ][mu]
754+ *fockMatrix[moB][nu];
755+ double tmpMuNu03 = fockMatrix[moA][mu]
756+ *fockMatrix[moB][nu];
757+ double tmpMuNu04 = fockMatrix[moI][mu]
758+ *fockMatrix[moJ][nu];
759+ double tmpMuNu09 = 2.0*fockMatrix[moI][mu]
760+ *fockMatrix[moA][nu];
761+ double tmpMuNu10 = 2.0*fockMatrix[moB][mu]
762+ *fockMatrix[moJ][nu];
763+ double tmpMuNu11 = fockMatrix[moB][mu]
764+ *fockMatrix[moA][nu];
765+ double tmpMuNu12 = fockMatrix[moJ][mu]
766+ *fockMatrix[moI][nu];
751767 for(int lambda=firstAOIndexB; lambda<=lastAOIndexB; lambda++){
768+ double tmpMuNuLamda01 = tmpMuNu01*fockMatrix[moJ][lambda];
769+ double tmpMuNuLamda02 = tmpMuNu02*fockMatrix[moA][lambda];
770+ double tmpMuNuLamda03 = tmpMuNu03*fockMatrix[moI][lambda];
771+ double tmpMuNuLamda04 = tmpMuNu04*fockMatrix[moA][lambda];
772+ double tmpMuNuLamda05 = tmpMuNu01*fockMatrix[moB][lambda];
773+ double tmpMuNuLamda06 = tmpMuNu02*fockMatrix[moI][lambda];
774+ double tmpMuNuLamda07 = tmpMuNu03*fockMatrix[moJ][lambda];
775+ double tmpMuNuLamda08 = tmpMuNu04*fockMatrix[moB][lambda];
776+ double tmpMuNuLamda09 = tmpMuNu09*fockMatrix[moJ][lambda];
777+ double tmpMuNuLamda10 = tmpMuNu10*fockMatrix[moA][lambda];
778+ double tmpMuNuLamda11 = tmpMuNu11*fockMatrix[moI][lambda];
779+ double tmpMuNuLamda12 = tmpMuNu12*fockMatrix[moA][lambda];
780+ double tmpMuNuLamda13 = tmpMuNu09*fockMatrix[moB][lambda];
781+ double tmpMuNuLamda14 = tmpMuNu10*fockMatrix[moI][lambda];
782+ double tmpMuNuLamda15 = tmpMuNu11*fockMatrix[moJ][lambda];
783+ double tmpMuNuLamda16 = tmpMuNu12*fockMatrix[moB][lambda];
752784 for(int sigma=lambda; sigma<=lastAOIndexB; sigma++){
753785 OrbitalType orbitalSigma = atomB.GetValence(sigma-firstAOIndexB);
754786 gamma = this->twoElecTwoCore[A]
@@ -758,75 +790,27 @@ void Mndo::CalcCISMatrix(double** matrixCIS) const{
758790 [lambda-firstAOIndexB]
759791 [sigma-firstAOIndexB];
760792
761- value += 2.0*gamma*fockMatrix[moA][mu]
762- *fockMatrix[moI][nu]
763- *fockMatrix[moJ][lambda]
764- *fockMatrix[moB][sigma];
765- value += 2.0*gamma*fockMatrix[moA][lambda]
766- *fockMatrix[moI][sigma]
767- *fockMatrix[moJ][mu]
768- *fockMatrix[moB][nu];
769- value -= gamma*fockMatrix[moA][mu]
770- *fockMatrix[moB][nu]
771- *fockMatrix[moI][lambda]
772- *fockMatrix[moJ][sigma];
773- value -= gamma*fockMatrix[moA][lambda]
774- *fockMatrix[moB][sigma]
775- *fockMatrix[moI][mu]
776- *fockMatrix[moJ][nu];
793+ value += gamma*tmpMuNuLamda01*fockMatrix[moB][sigma];
794+ value += gamma*tmpMuNuLamda02*fockMatrix[moI][sigma];
795+ value -= gamma*tmpMuNuLamda03*fockMatrix[moJ][sigma];
796+ value -= gamma*tmpMuNuLamda04*fockMatrix[moB][sigma];
777797 if(lambda != sigma){
778- value += 2.0*gamma*fockMatrix[moA][mu]
779- *fockMatrix[moI][nu]
780- *fockMatrix[moJ][sigma]
781- *fockMatrix[moB][lambda];
782- value += 2.0*gamma*fockMatrix[moA][sigma]
783- *fockMatrix[moI][lambda]
784- *fockMatrix[moJ][mu]
785- *fockMatrix[moB][nu];
786- value -= gamma*fockMatrix[moA][mu]
787- *fockMatrix[moB][nu]
788- *fockMatrix[moI][sigma]
789- *fockMatrix[moJ][lambda];
790- value -= gamma*fockMatrix[moA][sigma]
791- *fockMatrix[moB][lambda]
792- *fockMatrix[moI][mu]
793- *fockMatrix[moJ][nu];
798+ value += gamma*tmpMuNuLamda05*fockMatrix[moJ][sigma];
799+ value += gamma*tmpMuNuLamda06*fockMatrix[moA][sigma];
800+ value -= gamma*tmpMuNuLamda07*fockMatrix[moI][sigma];
801+ value -= gamma*tmpMuNuLamda08*fockMatrix[moA][sigma];
794802 }
795803 if(mu != nu){
796- value += 2.0*gamma*fockMatrix[moA][nu]
797- *fockMatrix[moI][mu]
798- *fockMatrix[moJ][lambda]
799- *fockMatrix[moB][sigma];
800- value += 2.0*gamma*fockMatrix[moA][lambda]
801- *fockMatrix[moI][sigma]
802- *fockMatrix[moJ][nu]
803- *fockMatrix[moB][mu];
804- value -= gamma*fockMatrix[moA][nu]
805- *fockMatrix[moB][mu]
806- *fockMatrix[moI][lambda]
807- *fockMatrix[moJ][sigma];
808- value -= gamma*fockMatrix[moA][lambda]
809- *fockMatrix[moB][sigma]
810- *fockMatrix[moI][nu]
811- *fockMatrix[moJ][mu];
804+ value += gamma*tmpMuNuLamda09*fockMatrix[moB][sigma];
805+ value += gamma*tmpMuNuLamda10*fockMatrix[moI][sigma];
806+ value -= gamma*tmpMuNuLamda11*fockMatrix[moJ][sigma];
807+ value -= gamma*tmpMuNuLamda12*fockMatrix[moB][sigma];
812808 }
813809 if(mu != nu && lambda != sigma){
814- value += 2.0*gamma*fockMatrix[moA][nu]
815- *fockMatrix[moI][mu]
816- *fockMatrix[moJ][sigma]
817- *fockMatrix[moB][lambda];
818- value += 2.0*gamma*fockMatrix[moA][sigma]
819- *fockMatrix[moI][lambda]
820- *fockMatrix[moJ][nu]
821- *fockMatrix[moB][mu];
822- value -= gamma*fockMatrix[moA][nu]
823- *fockMatrix[moB][mu]
824- *fockMatrix[moI][sigma]
825- *fockMatrix[moJ][lambda];
826- value -= gamma*fockMatrix[moA][sigma]
827- *fockMatrix[moB][lambda]
828- *fockMatrix[moI][nu]
829- *fockMatrix[moJ][mu];
810+ value += gamma*tmpMuNuLamda13*fockMatrix[moJ][sigma];
811+ value += gamma*tmpMuNuLamda14*fockMatrix[moA][sigma];
812+ value -= gamma*tmpMuNuLamda15*fockMatrix[moI][sigma];
813+ value -= gamma*tmpMuNuLamda16*fockMatrix[moA][sigma];
830814 }
831815 }
832816 }
@@ -836,7 +820,13 @@ void Mndo::CalcCISMatrix(double** matrixCIS) const{
836820 else{
837821 for(int mu=firstAOIndexA; mu<=lastAOIndexA; mu++){
838822 for(int nu=firstAOIndexA; nu<=lastAOIndexA; nu++){
823+ double tmpMuNu01 = 2.0*fockMatrix[moA][mu]
824+ *fockMatrix[moI][nu];
825+ double tmpMuNu02 = fockMatrix[moA][mu]
826+ *fockMatrix[moB][nu];
839827 for(int lambda=firstAOIndexB; lambda<=lastAOIndexB; lambda++){
828+ double tmpMuNuLamda01 = tmpMuNu01*fockMatrix[moJ][lambda];
829+ double tmpMuNuLamda02 = tmpMuNu02*fockMatrix[moI][lambda];
840830 for(int sigma=firstAOIndexB; sigma<=lastAOIndexB; sigma++){
841831 if(mu==nu && lambda==sigma){
842832 OrbitalType orbitalMu = atomA.GetValence(mu-firstAOIndexA);
@@ -851,14 +841,8 @@ void Mndo::CalcCISMatrix(double** matrixCIS) const{
851841 else{
852842 gamma = 0.0;
853843 }
854- value += 2.0*gamma*fockMatrix[moA][mu]
855- *fockMatrix[moI][nu]
856- *fockMatrix[moJ][lambda]
857- *fockMatrix[moB][sigma];
858- value -= gamma*fockMatrix[moA][mu]
859- *fockMatrix[moB][nu]
860- *fockMatrix[moI][lambda]
861- *fockMatrix[moJ][sigma];
844+ value += gamma*tmpMuNuLamda01*fockMatrix[moB][sigma];
845+ value -= gamma*tmpMuNuLamda02*fockMatrix[moJ][sigma];
862846 }
863847 }
864848 }
@@ -2947,11 +2931,11 @@ void Mndo::FreeTempMatricesSolveCPHF(double*** matrixCPHF,
29472931
29482932 // see [PT_1996, PT_1997]
29492933 void Mndo::CalcZMatrixForce(const vector<int>& elecStates){
2934+#ifdef MOLDS_DBG
29502935 if(this->etaMatrixForce == NULL){
2951- stringstream ss;
2952- ss << this->errorMessageCalcZMatrixForceEtaNull;
2953- throw MolDSException(ss.str());
2936+ throw MolDSException(this->errorMessageCalcZMatrixForceEtaNull);
29542937 }
2938+#endif
29552939 this->CheckZMatrixForce(elecStates);
29562940
29572941 // creat MO-index-pair for Q variables.
@@ -3511,17 +3495,15 @@ void Mndo::FreeTempMatricesCalcForce(double**** diatomicOverlapAOs1stDerivs, dou
35113495
35123496 void Mndo::CalcTwoElecTwoCore(double****** twoElecTwoCore,
35133497 const Molecule& molecule) const{
3498+#ifdef MOLDS_DBG
35143499 if(twoElecTwoCore == NULL){
3515- stringstream ss;
3516- ss << this->errorMessageCalcTwoElecTwoCoreNullMatrix;
3517- throw MolDSException(ss.str());
3500+ throw MolDSException(this->errorMessageCalcTwoElecTwoCoreNullMatrix);
35183501 }
3519- else{
3520- MallocerFreer::GetInstance()->Initialize<double>(twoElecTwoCore,
3521- molecule.GetNumberAtoms(),
3522- molecule.GetNumberAtoms(),
3523- dxy, dxy, dxy, dxy);
3524- }
3502+#endif
3503+ MallocerFreer::GetInstance()->Initialize<double>(twoElecTwoCore,
3504+ molecule.GetNumberAtoms(),
3505+ molecule.GetNumberAtoms(),
3506+ dxy, dxy, dxy, dxy);
35253507
35263508 stringstream ompErrors;
35273509 #pragma omp parallel
@@ -3586,14 +3568,12 @@ void Mndo::CalcDiatomicTwoElecTwoCore(double**** matrix, int indexAtomA, int ind
35863568 throw MolDSException(ss.str());
35873569 }
35883570
3571+#ifdef MOLDS_DBG
35893572 if(matrix == NULL){
3590- stringstream ss;
3591- ss << this->errorMessageCalcDiatomicTwoElecTwoCoreNullMatrix;
3592- throw MolDSException(ss.str());
3573+ throw MolDSException(this->errorMessageCalcDiatomicTwoElecTwoCoreNullMatrix);
35933574 }
3594- else{
3595- MallocerFreer::GetInstance()->Initialize<double>(matrix, dxy, dxy, dxy, dxy);
3596- }
3575+#endif
3576+ MallocerFreer::GetInstance()->Initialize<double>(matrix, dxy, dxy, dxy, dxy);
35973577
35983578 // calclation in diatomic frame
35993579 for(int mu=0; mu<atomA.GetValenceSize(); mu++){
@@ -3668,19 +3648,17 @@ void Mndo::CalcDiatomicTwoElecTwoCore1stDerivatives(double***** matrix,
36683648 throw MolDSException(ss.str());
36693649 }
36703650
3651+#ifdef MOLDS_DBG
36713652 if(matrix == NULL){
3672- stringstream ss;
3673- ss << this->errorMessageCalcDiatomicTwoElecTwoCore1stDerivativesNullMatrix;
3674- throw MolDSException(ss.str());
3653+ throw MolDSException(this->errorMessageCalcDiatomicTwoElecTwoCore1stDerivativesNullMatrix);
36753654 }
3676- else{
3677- MallocerFreer::GetInstance()->Initialize<double>(matrix,
3678- dxy,
3679- dxy,
3680- dxy,
3681- dxy,
3682- CartesianType_end);
3683- }
3655+#endif
3656+ MallocerFreer::GetInstance()->Initialize<double>(matrix,
3657+ dxy,
3658+ dxy,
3659+ dxy,
3660+ dxy,
3661+ CartesianType_end);
36843662
36853663 double** rotatingMatrix = NULL;
36863664 double*** rotMat1stDerivatives = NULL;
@@ -3766,20 +3744,18 @@ void Mndo::CalcDiatomicTwoElecTwoCore2ndDerivatives(double****** matrix,
37663744 throw MolDSException(ss.str());
37673745 }
37683746
3747+#ifdef MOLDS_DBG
37693748 if(matrix == NULL){
3770- stringstream ss;
3771- ss << this->errorMessageCalcDiatomicTwoElecTwoCore2ndDerivativesNullMatrix;
3772- throw MolDSException(ss.str());
3773- }
3774- else{
3775- MallocerFreer::GetInstance()->Initialize<double>(matrix,
3776- dxy,
3777- dxy,
3778- dxy,
3779- dxy,
3780- CartesianType_end,
3781- CartesianType_end);
3782- }
3749+ throw MolDSException(this->errorMessageCalcDiatomicTwoElecTwoCore2ndDerivativesNullMatrix);
3750+ }
3751+#endif
3752+ MallocerFreer::GetInstance()->Initialize<double>(matrix,
3753+ dxy,
3754+ dxy,
3755+ dxy,
3756+ dxy,
3757+ CartesianType_end,
3758+ CartesianType_end);
37833759
37843760 double** rotatingMatrix = NULL;
37853761 double*** rotMat1stDerivatives = NULL;
--- a/src/pm3/Pm3.cpp
+++ b/src/pm3/Pm3.cpp
@@ -25,6 +25,7 @@
2525 #include<vector>
2626 #include<boost/format.hpp>
2727 #include"../base/PrintController.h"
28+#include"../base/MolDSException.h"
2829 #include"../base/Uncopyable.h"
2930 #include"../base/Enums.h"
3031 #include"../base/EularAngle.h"
--- a/src/pm3/Pm3D.cpp
+++ b/src/pm3/Pm3D.cpp
@@ -25,6 +25,7 @@
2525 #include<vector>
2626 #include<boost/format.hpp>
2727 #include"../base/PrintController.h"
28+#include"../base/MolDSException.h"
2829 #include"../base/Uncopyable.h"
2930 #include"../base/Enums.h"
3031 #include"../base/EularAngle.h"
--- a/src/pm3/Pm3Pddg.cpp
+++ b/src/pm3/Pm3Pddg.cpp
@@ -25,6 +25,7 @@
2525 #include<vector>
2626 #include<boost/format.hpp>
2727 #include"../base/PrintController.h"
28+#include"../base/MolDSException.h"
2829 #include"../base/Uncopyable.h"
2930 #include"../base/Enums.h"
3031 #include"../base/EularAngle.h"
--- a/src/wrappers/Blas.cpp
+++ b/src/wrappers/Blas.cpp
@@ -39,6 +39,7 @@
3939 #include"../base/PrintController.h"
4040 #include"../base/MolDSException.h"
4141 #include"../base/Uncopyable.h"
42+#include"../base/MallocerFreer.h"
4243 #include"Blas.h"
4344 using namespace std;
4445 using namespace MolDS_base;
@@ -310,6 +311,56 @@ void Blas::Dgemm(bool isColumnMajorMatrixA,
310311 #endif
311312 }
312313
314+// matrixD = matrixA*matrixB*matrixC
315+// matrixA: m*k-matrix (matrixA[m][k] in row-major (C/C++ style))
316+// matrixB: k*l-matrix (matrixB[k][n] in row-major (C/C++ style))
317+// matrixC: k*n-matrix (matrixC[k][n] in row-major (C/C++ style))
318+// matrixD: m*n-matrix (matrixC[m][n] in row-major (C/C++ style))
319+void Blas::Dgemmm(molds_blas_int m, molds_blas_int n, molds_blas_int k, molds_blas_int l,
320+ double const* const* matrixA,
321+ double const* const* matrixB,
322+ double const* const* matrixC,
323+ double** matrixD) const{
324+ bool isColumnMajorMatrixA = false; // because, in general, C/C++ style is row-major.
325+ bool isColumnMajorMatrixB = false; // because, in general, C/C++ style is row-major.
326+ bool isColumnMajorMatrixC = false; // because, in general, C/C++ style is row-major.
327+ double alpha=1.0;
328+ double beta =0.0;
329+ this->Dgemmm(isColumnMajorMatrixA, isColumnMajorMatrixB, isColumnMajorMatrixC, m, n, k, l, alpha, matrixA, matrixB, matrixC, beta, matrixD);
330+}
331+
332+// matrixD = alpha*matrixA*matrixB*matrixC + beta*matrixD
333+// matrixA: m*k-matrix
334+// matrixB: k*l-matrix
335+// matrixC: l*n-matrix
336+// matrixD: m*n-matrix (matrixC[m][n] in row-major (C/C++ style))
337+void Blas::Dgemmm(bool isColumnMajorMatrixA,
338+ bool isColumnMajorMatrixB,
339+ bool isColumnMajorMatrixC,
340+ molds_blas_int m, molds_blas_int n, molds_blas_int k, molds_blas_int l,
341+ double alpha,
342+ double const* const* matrixA,
343+ double const* const* matrixB,
344+ double const* const* matrixC,
345+ double beta,
346+ double** matrixD) const{
347+
348+ double alphaBC = 1.0;
349+ double betaBC = 0.0;
350+ bool isColumnMajorMatrixBC = false;
351+ double** matrixBC = NULL;
352+ try{
353+ MallocerFreer::GetInstance()->Malloc<double>(&matrixBC, k, n);
354+ this->Dgemm(isColumnMajorMatrixB, isColumnMajorMatrixC, k, n, l, alphaBC, matrixB, matrixC, betaBC, matrixBC);
355+ this->Dgemm(isColumnMajorMatrixA, isColumnMajorMatrixBC, m, n, k, alpha, matrixA, matrixBC, beta, matrixD );
356+ }
357+ catch(MolDSException ex){
358+ MallocerFreer::GetInstance()->Free<double>(&matrixBC, k, n);
359+ throw ex;
360+ }
361+ MallocerFreer::GetInstance()->Free<double>(&matrixBC, k, n);
362+}
363+
313364 // matrixC = matrixA*matrixA^T
314365 // matrixA: n*k-matrix
315366 // matrixC: n*n-matrix,symmetric (Use the upper triangular part, and copy it to the lower part.)
--- a/src/wrappers/Blas.h
+++ b/src/wrappers/Blas.h
@@ -102,15 +102,30 @@ public:
102102 double const* const* matrixB,
103103 double beta,
104104 double** matrixC) const;
105- void Dsyrk(molds_blas_int n, molds_blas_int k,
106- double const *const* matrixA,
107- double** matrixC)const;
108- void Dsyrk(molds_blas_int n, molds_blas_int k,
109- bool isMatrixAColumnMajor,
110- bool isMatrixATransposed,
111- bool isLowerTriangularPartMatrixCUsed,
112- double alpha, double const* const* matrixA,
113- double beta, double** matrixC)const;
105+ void Dgemmm(molds_blas_int m, molds_blas_int n, molds_blas_int k, molds_blas_int l,
106+ double const* const* matrixA,
107+ double const* const* matrixB,
108+ double const* const* matrixC,
109+ double** matrixD) const;
110+ void Dgemmm(bool isColumnMajorMatrixA,
111+ bool isColumnMajorMatrixB,
112+ bool isColumnMajorMatrixC,
113+ molds_blas_int m, molds_blas_int n, molds_blas_int k, molds_blas_int l,
114+ double alpha,
115+ double const* const* matrixA,
116+ double const* const* matrixB,
117+ double const* const* matrixC,
118+ double beta,
119+ double** matrixD) const;
120+ void Dsyrk(molds_blas_int n, molds_blas_int k,
121+ double const *const* matrixA,
122+ double** matrixC)const;
123+ void Dsyrk(molds_blas_int n, molds_blas_int k,
124+ bool isMatrixAColumnMajor,
125+ bool isMatrixATransposed,
126+ bool isLowerTriangularPartMatrixCUsed,
127+ double alpha, double const* const* matrixA,
128+ double beta, double** matrixC)const;
114129 private:
115130 Blas();
116131 ~Blas();
--- a/src/zindo/ZindoS.cpp
+++ b/src/zindo/ZindoS.cpp
@@ -129,8 +129,8 @@ void ZindoS::SetMessages(){
129129 = "Error in zindo::ZindoS::GetElectronicEnergy: Set electronic state is not calculated by CIS.\n";
130130 this->errorMessageGetElectronicEnergyNULLCISEnergy
131131 = "Error in zindo::ZindoS::GetElectronicEnergy: excitedEnergies is NULL\n";
132- this->errorMessageGetElectronicTransitionDipoleMomentBadState
133- = "Error in zindo::ZindoS::GetElectronicTransitionDipoleMoment: Bad eigen state is set to calculate the transition dipole moment. Note taht state=0 means the ground state and other state = i means the i-th excited state in below.\n";
132+ this->errorMessageCalcElectronicTransitionDipoleMomentBadState
133+ = "Error in zindo::ZindoS::CalcElectronicTransitionDipoleMoment: Bad eigen state is set to calculate the transition dipole moment. Note taht state=0 means the ground state and other state = i means the i-th excited state in below.\n";
134134 this->errorMessageCalcFrequenciesNormalModesBadTheory
135135 = "Error in zindo::ZindoS::CalcFrequenciesNormalModesBadTheory: ZINDO/S is not supported for frequency (normal mode) analysis.\n";
136136 this->messageSCFMetConvergence = "\n\n\n\t\tZINDO/S-SCF met convergence criterion(^^b\n\n\n";
@@ -219,6 +219,7 @@ double ZindoS::GetFockDiagElement(const Atom& atomA,
219219 OrbitalType orbitalSigma;
220220 int sigma;
221221 int atomBNumberValence = atomB.GetValenceSize();
222+ double rAB = molecule.GetDistanceAtoms(atomA, atomB);
222223 for(int i=0; i<atomBNumberValence; i++){
223224 sigma = i + atomB.GetFirstAOIndex();
224225 orbitalSigma = atomB.GetValence(i);
@@ -226,10 +227,11 @@ double ZindoS::GetFockDiagElement(const Atom& atomA,
226227 *this->GetNishimotoMatagaTwoEleInt(atomA,
227228 orbitalMu,
228229 atomB,
229- orbitalSigma);
230+ orbitalSigma,
231+ rAB);
230232 }
231233 temp -= atomB.GetCoreCharge()
232- *this->GetNishimotoMatagaTwoEleInt(atomA, s, atomB, s);
234+ *this->GetNishimotoMatagaTwoEleInt(atomA, s, atomB, s, rAB);
233235 }
234236 }
235237 value += temp;
@@ -548,6 +550,13 @@ double ZindoS::GetExchangeInt(OrbitalType orbital1, OrbitalType orbital2, const
548550 double ZindoS::GetNishimotoMatagaTwoEleInt(const Atom& atomA, OrbitalType orbitalA,
549551 const Atom& atomB, OrbitalType orbitalB) const{
550552 double r = this->molecule->GetDistanceAtoms(atomA, atomB);
553+ return this->GetNishimotoMatagaTwoEleInt(atomA, orbitalA, atomB, orbitalB,r);
554+}
555+
556+// ref. [MN_1957] and (5a) in [AEZ_1986]
557+double ZindoS::GetNishimotoMatagaTwoEleInt(const Atom& atomA, OrbitalType orbitalA,
558+ const Atom& atomB, OrbitalType orbitalB,
559+ const double rAB) const{
551560 double gammaAA;
552561 if(orbitalA == s ||
553562 orbitalA == px ||
@@ -596,7 +605,8 @@ double ZindoS::GetNishimotoMatagaTwoEleInt(const Atom& atomA, OrbitalType orbita
596605 throw MolDSException(ss.str());
597606 }
598607
599- return this->nishimotoMatagaParamA/( r+this->nishimotoMatagaParamB/(gammaAA+gammaBB) );
608+ double gamma=gammaAA+gammaBB;
609+ return this->nishimotoMatagaParamA/( rAB+this->nishimotoMatagaParamB/gamma );
600610
601611 }
602612
@@ -604,10 +614,23 @@ double ZindoS::GetNishimotoMatagaTwoEleInt(const Atom& atomA, OrbitalType orbita
604614 // For Nishimoto-Mataga, See ZindoS::GetNishimotoMatagaTwoEleInt
605615 // or ref. [MN_1957] and (5a) in [AEZ_1986]
606616 double ZindoS::GetNishimotoMatagaTwoEleInt1stDerivative(const Atom& atomA,
607- OrbitalType orbitalA,
608- const Atom& atomB,
609- OrbitalType orbitalB,
610- CartesianType axisA) const{
617+ OrbitalType orbitalA,
618+ const Atom& atomB,
619+ OrbitalType orbitalB,
620+ CartesianType axisA) const{
621+ double r = this->molecule->GetDistanceAtoms(atomA, atomB);
622+ return this->GetNishimotoMatagaTwoEleInt1stDerivative(atomA, orbitalA, atomB, orbitalB, r, axisA);
623+}
624+
625+// First derivative of Nishimoto-Mataga related to the coordinate of atom A.
626+// For Nishimoto-Mataga, See ZindoS::GetNishimotoMatagaTwoEleInt
627+// or ref. [MN_1957] and (5a) in [AEZ_1986]
628+double ZindoS::GetNishimotoMatagaTwoEleInt1stDerivative(const Atom& atomA,
629+ OrbitalType orbitalA,
630+ const Atom& atomB,
631+ OrbitalType orbitalB,
632+ const double rAB,
633+ CartesianType axisA) const{
611634 double gammaAA;
612635 if(orbitalA == s ||
613636 orbitalA == px ||
@@ -656,14 +679,51 @@ double ZindoS::GetNishimotoMatagaTwoEleInt1stDerivative(const Atom& atomA,
656679 throw MolDSException(ss.str());
657680 }
658681
659- double r = this->molecule->GetDistanceAtoms(atomA, atomB);
660682 double dCartesian = atomA.GetXyz()[axisA] - atomB.GetXyz()[axisA];
661- double value = -1.0*dCartesian/r;
683+ double value = -1.0*dCartesian/rAB;
662684 value *= this->nishimotoMatagaParamA;
663- value *= pow( r+this->nishimotoMatagaParamB/(gammaAA+gammaBB) ,-2.0);
685+ value *= pow( rAB+this->nishimotoMatagaParamB/(gammaAA+gammaBB) ,-2.0);
664686 return value;
665687 }
666688
689+void ZindoS::CalcNishimotoMatagaMatrix(double**** nishimotoMatagaMatrix, const Molecule& molecule) const{
690+ int totalNumberAtoms = molecule.GetNumberAtoms();
691+ stringstream ompErrors;
692+#pragma omp parallel for schedule(auto)
693+ for(int A=0; A<totalNumberAtoms; A++){
694+ try{
695+ const Atom& atomA = *molecule.GetAtom(A);
696+ int firstAOIndexA = atomA.GetFirstAOIndex();
697+ int lastAOIndexA = atomA.GetLastAOIndex();
698+ for(int mu=firstAOIndexA; mu<=lastAOIndexA; mu++){
699+ OrbitalType orbitalMu = atomA.GetValence(mu-firstAOIndexA);
700+ for(int B=A; B<totalNumberAtoms; B++){
701+ const Atom& atomB = *molecule.GetAtom(B);
702+ int firstAOIndexB = atomB.GetFirstAOIndex();
703+ int lastAOIndexB = atomB.GetLastAOIndex();
704+ double rAB = molecule.GetDistanceAtoms(atomA, atomB);
705+ for(int nu=firstAOIndexB; nu<=lastAOIndexB; nu++){
706+ OrbitalType orbitalNu = atomB.GetValence(nu-firstAOIndexB);
707+ nishimotoMatagaMatrix[A][orbitalMu][B][orbitalNu] = this->GetNishimotoMatagaTwoEleInt(atomA,
708+ orbitalMu,
709+ atomB,
710+ orbitalNu,
711+ rAB);
712+ }
713+ }
714+ }
715+ }
716+ catch(MolDSException ex){
717+#pragma omp critical
718+ ompErrors << ex.what() << endl ;
719+ }
720+ }
721+ // Exception throwing for omp-region
722+ if(!ompErrors.str().empty()){
723+ throw MolDSException(ompErrors.str());
724+ }
725+}
726+
667727 void ZindoS::CalcDiatomicOverlapAOsInDiatomicFrame(double** diatomicOverlapAOs,
668728 const Atom& atomA,
669729 const Atom& atomB) const{
@@ -839,7 +899,7 @@ void ZindoS::CalcOverlapESsWithAnotherElectronicStructure(double** overlapESs,
839899 MallocerFreer::GetInstance()->Free<double>(&tmpMatrix, dimOverlapSingletSDs, dimOverlapESs);
840900 }
841901
842-// The order of mol, moJ, moK, moL is consistent with Eq. (9) in [RZ_1973]
902+// The order of moI, moJ, moK, moL is consistent with Eq. (9) in [RZ_1973]
843903 double ZindoS::GetMolecularIntegralElement(int moI, int moJ, int moK, int moL,
844904 const Molecule& molecule,
845905 double const* const* fockMatrix,
@@ -984,24 +1044,146 @@ void ZindoS::DoCIS(){
9841044 }
9851045
9861046 void ZindoS::CalcCISProperties(){
1047+//calculate dipole moments and transitiondipolemoment
1048+{
1049+ double*** dipoleMOs = NULL;
1050+ double** overlapMOs = NULL;
1051+ int totalNumberAOs = this->molecule->GetTotalNumberAOs();
1052+ int numberOcc = this->molecule->GetTotalNumberValenceElectrons()/2;
1053+ int numberActiveOcc = Parameters::GetInstance()->GetActiveOccCIS();
1054+ int numberActiveVir = Parameters::GetInstance()->GetActiveVirCIS();
1055+ MallocerFreer::GetInstance()->Malloc<double>(&dipoleMOs, CartesianType_end, totalNumberAOs, totalNumberAOs);
1056+ MallocerFreer::GetInstance()->Malloc<double>(&overlapMOs, totalNumberAOs, totalNumberAOs);
1057+ double alpha=1.0;
1058+ double beta =0.0;
1059+ //double ompStartTime = omp_get_wtime();
1060+ MolDS_wrappers::Blas::GetInstance()->Dgemmm(false, false, true, totalNumberAOs, totalNumberAOs, totalNumberAOs, totalNumberAOs,
1061+ alpha,
1062+ this->fockMatrix,
1063+ this->cartesianMatrix[XAxis],
1064+ this->fockMatrix,
1065+ beta,
1066+ dipoleMOs[XAxis]);
1067+ MolDS_wrappers::Blas::GetInstance()->Dgemmm(false, false, true, totalNumberAOs, totalNumberAOs, totalNumberAOs, totalNumberAOs,
1068+ alpha,
1069+ this->fockMatrix,
1070+ this->cartesianMatrix[YAxis],
1071+ this->fockMatrix,
1072+ beta,
1073+ dipoleMOs[YAxis]);
1074+ MolDS_wrappers::Blas::GetInstance()->Dgemmm(false, false, true, totalNumberAOs, totalNumberAOs, totalNumberAOs, totalNumberAOs,
1075+ alpha,
1076+ this->fockMatrix,
1077+ this->cartesianMatrix[ZAxis],
1078+ this->fockMatrix,
1079+ beta,
1080+ dipoleMOs[ZAxis]);
1081+
1082+ double const* centerOfDipole = this->molecule->GetXyzCOC();
1083+ // set orign of dipole
1084+ MolDS_wrappers::Blas::GetInstance()->Dgemmm(false, false, true, totalNumberAOs, totalNumberAOs, totalNumberAOs, totalNumberAOs,
1085+ alpha,
1086+ this->fockMatrix,
1087+ this->overlapAOs,
1088+ this->fockMatrix,
1089+ beta,
1090+ overlapMOs);
1091+ MolDS_wrappers::Blas::GetInstance()->Daxpy(totalNumberAOs*totalNumberAOs,
1092+ -centerOfDipole[XAxis],
1093+ &overlapMOs[0][0],
1094+ &dipoleMOs[XAxis][0][0]);
1095+ MolDS_wrappers::Blas::GetInstance()->Daxpy(totalNumberAOs*totalNumberAOs,
1096+ -centerOfDipole[YAxis],
1097+ &overlapMOs[0][0],
1098+ &dipoleMOs[YAxis][0][0]);
1099+ MolDS_wrappers::Blas::GetInstance()->Daxpy(totalNumberAOs*totalNumberAOs,
1100+ -centerOfDipole[ZAxis],
1101+ &overlapMOs[0][0],
1102+ &dipoleMOs[ZAxis][0][0]);
1103+
9871104
9881105 // dipole moments of excited states
989- this->CalcElectronicDipoleMomentsExcitedState(this->electronicTransitionDipoleMoments,
990- this->fockMatrix,
991- this->matrixCIS,
992- this->cartesianMatrix,
993- *this->molecule,
994- this->orbitalElectronPopulation,
995- this->overlapAOs);
996-
1106+ //this->CalcElectronicDipoleMomentsExcitedStates(this->electronicTransitionDipoleMoments,
1107+ // this->fockMatrix,
1108+ // this->matrixCIS,
1109+ // this->cartesianMatrix,
1110+ // *this->molecule,
1111+ // this->orbitalElectronPopulation,
1112+ // this->overlapAOs);
1113+ int groundState = 0;
1114+ for(int k=0; k<Parameters::GetInstance()->GetNumberExcitedStatesCIS(); k++){
1115+ int excitedState = k+1; // (k+1)-th excited state
1116+ this->electronicTransitionDipoleMoments[excitedState][excitedState][XAxis] = this->electronicTransitionDipoleMoments[groundState][groundState][XAxis];
1117+ this->electronicTransitionDipoleMoments[excitedState][excitedState][YAxis] = this->electronicTransitionDipoleMoments[groundState][groundState][YAxis];
1118+ this->electronicTransitionDipoleMoments[excitedState][excitedState][ZAxis] = this->electronicTransitionDipoleMoments[groundState][groundState][ZAxis];
1119+ for(int l=0; l<this->matrixCISdimension; l++){
1120+ // single excitation from I-th (occupied)MO to A-th (virtual)MO
1121+ int moI = this->GetActiveOccIndex(*this->molecule, l);
1122+ int moA = this->GetActiveVirIndex(*this->molecule, l);
1123+ double temp = matrixCIS[k][l]*matrixCIS[k][l];
1124+ this->electronicTransitionDipoleMoments[excitedState][excitedState][XAxis] += temp*(-dipoleMOs[XAxis][moI][moI]+dipoleMOs[XAxis][moA][moA]);
1125+ this->electronicTransitionDipoleMoments[excitedState][excitedState][YAxis] += temp*(-dipoleMOs[YAxis][moI][moI]+dipoleMOs[YAxis][moA][moA]);
1126+ this->electronicTransitionDipoleMoments[excitedState][excitedState][ZAxis] += temp*(-dipoleMOs[ZAxis][moI][moI]+dipoleMOs[ZAxis][moA][moA]);
1127+ }
1128+ }
1129+
9971130 // transition dipole moment
998- this->CalcElectronicTransitionDipoleMoments(this->electronicTransitionDipoleMoments,
999- this->fockMatrix,
1000- this->matrixCIS,
1001- this->cartesianMatrix,
1002- *this->molecule,
1003- this->orbitalElectronPopulation,
1004- this->overlapAOs);
1131+ //this->CalcElectronicTransitionDipoleMoments(this->electronicTransitionDipoleMoments,
1132+ // this->fockMatrix,
1133+ // this->matrixCIS,
1134+ // this->cartesianMatrix,
1135+ // *this->molecule,
1136+ // this->orbitalElectronPopulation,
1137+ // this->overlapAOs);
1138+ for(int k=0; k<Parameters::GetInstance()->GetNumberExcitedStatesCIS(); k++){
1139+ int excitedState = k+1; // (k+1)-th excited state
1140+ this->electronicTransitionDipoleMoments[excitedState][groundState][XAxis] = 0.0;
1141+ this->electronicTransitionDipoleMoments[excitedState][groundState][YAxis] = 0.0;
1142+ this->electronicTransitionDipoleMoments[excitedState][groundState][ZAxis] = 0.0;
1143+ for(int l=0; l<this->matrixCISdimension; l++){
1144+ // single excitation from I-th (occupied)MO to A-th (virtual)MO
1145+ int moI = this->GetActiveOccIndex(*this->molecule, l);
1146+ int moA = this->GetActiveVirIndex(*this->molecule, l);
1147+ //double temp = matrixCIS[k][l]*matrixCIS[k][l];
1148+ double temp = this->matrixCIS[k][l]*sqrt(2.0);
1149+ this->electronicTransitionDipoleMoments[excitedState][groundState][XAxis] += temp*dipoleMOs[XAxis][moA][moI];
1150+ this->electronicTransitionDipoleMoments[excitedState][groundState][YAxis] += temp*dipoleMOs[YAxis][moA][moI];
1151+ this->electronicTransitionDipoleMoments[excitedState][groundState][ZAxis] += temp*dipoleMOs[ZAxis][moA][moI];
1152+ }
1153+ }
1154+ if(Parameters::GetInstance()->RequiresAllTransitionDipoleMomentsCIS()){
1155+ for(int k=0; k<Parameters::GetInstance()->GetNumberExcitedStatesCIS(); k++){
1156+ int departureExcitedState = k+1; // (k+1)-th excited state
1157+ for(int l=k+1; l<Parameters::GetInstance()->GetNumberExcitedStatesCIS(); l++){
1158+ int destinationExcitedState = l+1; // (l+1)-th excited state
1159+ this->electronicTransitionDipoleMoments[destinationExcitedState][departureExcitedState][XAxis] = 0.0;
1160+ this->electronicTransitionDipoleMoments[destinationExcitedState][departureExcitedState][YAxis] = 0.0;
1161+ this->electronicTransitionDipoleMoments[destinationExcitedState][departureExcitedState][ZAxis] = 0.0;
1162+ for(int l=0; l<this->matrixCISdimension; l++){
1163+ // single excitation from I-th (occupied)MO to A-th (virtual)MO
1164+ int moI = this->GetActiveOccIndex(*this->molecule, l);
1165+ int moA = this->GetActiveVirIndex(*this->molecule, l);
1166+ double temp = matrixCIS[departureExcitedState-1][l]*matrixCIS[destinationExcitedState-1][l];
1167+ this->electronicTransitionDipoleMoments[destinationExcitedState][departureExcitedState][XAxis] += temp*(-dipoleMOs[XAxis][moI][moI]+dipoleMOs[XAxis][moA][moA]);
1168+ this->electronicTransitionDipoleMoments[destinationExcitedState][departureExcitedState][YAxis] += temp*(-dipoleMOs[YAxis][moI][moI]+dipoleMOs[YAxis][moA][moA]);
1169+ this->electronicTransitionDipoleMoments[destinationExcitedState][departureExcitedState][ZAxis] += temp*(-dipoleMOs[ZAxis][moI][moI]+dipoleMOs[ZAxis][moA][moA]);
1170+ }
1171+ }
1172+ }
1173+
1174+ for(int k=0; k<Parameters::GetInstance()->GetNumberExcitedStatesCIS()+1; k++){
1175+ for(int l=k+1; l<Parameters::GetInstance()->GetNumberExcitedStatesCIS()+1; l++){
1176+ for(int axis=0; axis<CartesianType_end; axis++){
1177+ this->electronicTransitionDipoleMoments[k][l][axis]
1178+ = this->electronicTransitionDipoleMoments[l][k][axis];
1179+ }
1180+ }
1181+ }
1182+ }
1183+ MallocerFreer::GetInstance()->Free<double>(&dipoleMOs, CartesianType_end, totalNumberAOs, totalNumberAOs);
1184+ MallocerFreer::GetInstance()->Free<double>(&overlapMOs, totalNumberAOs, totalNumberAOs);
1185+}// end of "calculate dipole moments and transitiondipolemoment"
1186+
10051187
10061188
10071189 // free exciton energies
@@ -1028,30 +1210,27 @@ void ZindoS::CalcCISProperties(){
10281210 *this->molecule);
10291211 }
10301212
1031-void ZindoS::CalcElectronicDipoleMomentsExcitedState(double*** electronicTransitionDipoleMoments,
1032- double const* const* fockMatrix,
1033- double const* const* matrixCIS,
1034- double const* const* const* cartesianMatrix,
1035- const MolDS_base::Molecule& molecule,
1036- double const* const* orbitalElectronPopulation,
1037- double const* const* overlapAOs) const{
1213+void ZindoS::CalcElectronicDipoleMomentsExcitedStates(double*** electronicTransitionDipoleMoments,
1214+ double const* const* fockMatrix,
1215+ double const* const* matrixCIS,
1216+ double const* const* const* cartesianMatrix,
1217+ const MolDS_base::Molecule& molecule,
1218+ double const* const* orbitalElectronPopulation,
1219+ double const* const* overlapAOs) const{
10381220 int groundState = 0;
10391221 // dipole moment of excited states
10401222 for(int k=0; k<Parameters::GetInstance()->GetNumberExcitedStatesCIS(); k++){
10411223 int excitedState = k+1; // (k+1)-th excited state
1042- for(int axis=0; axis<CartesianType_end; axis++){
1043- electronicTransitionDipoleMoments[excitedState][excitedState][axis]
1044- = this->GetElectronicTransitionDipoleMoment(excitedState,
1045- excitedState,
1046- static_cast<CartesianType>(axis),
1047- fockMatrix,
1048- matrixCIS,
1049- cartesianMatrix,
1050- molecule,
1051- orbitalElectronPopulation,
1052- overlapAOs,
1053- electronicTransitionDipoleMoments[groundState][groundState]);
1054- }
1224+ this->CalcElectronicTransitionDipoleMoment(electronicTransitionDipoleMoments[excitedState][excitedState],
1225+ excitedState,
1226+ excitedState,
1227+ fockMatrix,
1228+ matrixCIS,
1229+ cartesianMatrix,
1230+ molecule,
1231+ orbitalElectronPopulation,
1232+ overlapAOs,
1233+ electronicTransitionDipoleMoments[groundState][groundState]);
10551234 }
10561235 }
10571236
@@ -1066,19 +1245,16 @@ void ZindoS::CalcElectronicTransitionDipoleMoments(double*** electronicTransitio
10661245 // transition dipole moments from ground state to excited states
10671246 for(int k=0; k<Parameters::GetInstance()->GetNumberExcitedStatesCIS(); k++){
10681247 int excitedState = k+1; // (k+1)-th excited state
1069- for(int axis=0; axis<CartesianType_end; axis++){
1070- this->electronicTransitionDipoleMoments[excitedState][groundState][axis]
1071- = this->GetElectronicTransitionDipoleMoment(excitedState,
1072- groundState,
1073- static_cast<CartesianType>(axis),
1074- this->fockMatrix,
1075- this->matrixCIS,
1076- this->cartesianMatrix,
1077- *this->molecule,
1078- this->orbitalElectronPopulation,
1079- this->overlapAOs,
1080- this->electronicTransitionDipoleMoments[groundState][groundState]);
1081- }
1248+ this->CalcElectronicTransitionDipoleMoment(electronicTransitionDipoleMoments[excitedState][groundState],
1249+ excitedState,
1250+ groundState,
1251+ fockMatrix,
1252+ matrixCIS,
1253+ cartesianMatrix,
1254+ molecule,
1255+ orbitalElectronPopulation,
1256+ overlapAOs,
1257+ electronicTransitionDipoleMoments[groundState][groundState]);
10821258 }
10831259
10841260 if(Parameters::GetInstance()->RequiresAllTransitionDipoleMomentsCIS()){
@@ -1087,70 +1263,79 @@ void ZindoS::CalcElectronicTransitionDipoleMoments(double*** electronicTransitio
10871263 int departureExcitedState = k+1; // (k+1)-th excited state
10881264 for(int l=k+1; l<Parameters::GetInstance()->GetNumberExcitedStatesCIS(); l++){
10891265 int destinationExcitedState = l+1; // (l+1)-th excited state
1090- for(int axis=0; axis<CartesianType_end; axis++){
1091- this->electronicTransitionDipoleMoments[destinationExcitedState][departureExcitedState][axis]
1092- = this->GetElectronicTransitionDipoleMoment(destinationExcitedState,
1093- departureExcitedState,
1094- static_cast<CartesianType>(axis),
1095- this->fockMatrix,
1096- this->matrixCIS,
1097- this->cartesianMatrix,
1098- *this->molecule,
1099- this->orbitalElectronPopulation,
1100- this->overlapAOs,
1101- this->electronicTransitionDipoleMoments[groundState][groundState]);
1102- }
1266+ this->CalcElectronicTransitionDipoleMoment(electronicTransitionDipoleMoments[destinationExcitedState][departureExcitedState],
1267+ destinationExcitedState,
1268+ departureExcitedState,
1269+ fockMatrix,
1270+ matrixCIS,
1271+ cartesianMatrix,
1272+ molecule,
1273+ orbitalElectronPopulation,
1274+ overlapAOs,
1275+ electronicTransitionDipoleMoments[groundState][groundState]);
11031276 }
11041277 }
11051278 for(int k=0; k<Parameters::GetInstance()->GetNumberExcitedStatesCIS()+1; k++){
11061279 for(int l=k+1; l<Parameters::GetInstance()->GetNumberExcitedStatesCIS()+1; l++){
11071280 for(int axis=0; axis<CartesianType_end; axis++){
1108- this->electronicTransitionDipoleMoments[k][l][axis]
1109- = this->electronicTransitionDipoleMoments[l][k][axis];
1281+ electronicTransitionDipoleMoments[k][l][axis]
1282+ = electronicTransitionDipoleMoments[l][k][axis];
11101283 }
11111284 }
11121285 }
11131286 }
11141287 }
11151288
1116-double ZindoS::GetElectronicTransitionDipoleMoment(int to, int from, CartesianType axis,
1117- double const* const* fockMatrix,
1118- double const* const* matrixCIS,
1119- double const* const* const* cartesianMatrix,
1120- const MolDS_base::Molecule& molecule,
1121- double const* const* orbitalElectronPopulation,
1122- double const* const* overlapAOs,
1123- double const* groundStateDipole) const{
1124- double value = 0.0;
1289+void ZindoS::CalcElectronicTransitionDipoleMoment(double* transitionDipoleMoment,
1290+ int to, int from,
1291+ double const* const* fockMatrix,
1292+ double const* const* matrixCIS,
1293+ double const* const* const* cartesianMatrix,
1294+ const MolDS_base::Molecule& molecule,
1295+ double const* const* orbitalElectronPopulation,
1296+ double const* const* overlapAOs,
1297+ double const* groundStateDipole) const{
1298+ double valueX = 0.0;
1299+ double valueY = 0.0;
1300+ double valueZ = 0.0;
1301+ double const* xyzCOC = molecule.GetXyzCOC();
11251302 int groundState = 0;
1303+ int totalNumberAOs = molecule.GetTotalNumberAOs();
11261304 stringstream ompErrors;
11271305 if(Parameters::GetInstance()->GetNumberExcitedStatesCIS() < from ||
11281306 Parameters::GetInstance()->GetNumberExcitedStatesCIS() < to ){
11291307 stringstream ss;
1130- ss << this->errorMessageGetElectronicTransitionDipoleMomentBadState;
1308+ ss << this->errorMessageCalcElectronicTransitionDipoleMomentBadState;
11311309 ss << this->errorMessageFromState << from << endl;
11321310 ss << this->errorMessageToState << to << endl;
1133- ss << this->errorMessageCartesianType << CartesianTypeStr(axis) << endl;
11341311 throw MolDSException(ss.str());
11351312 }
11361313
11371314 if(from != to){
11381315 if(from != groundState && to != groundState){
11391316 // transition dipole moment between different excited states
1140-#pragma omp parallel for reduction(+:value) schedule(auto)
1317+#pragma omp parallel for reduction(+:valueX,valueY,valueZ) schedule(auto)
11411318 for(int l=0; l<this->matrixCISdimension; l++){
11421319 try{
1143- double temp = 0.0;
1320+ double temp = 0.0;
1321+ double tempX = 0.0;
1322+ double tempY = 0.0;
1323+ double tempZ = 0.0;
11441324 // single excitation from I-th (occupied)MO to A-th (virtual)MO
11451325 int moI = this->GetActiveOccIndex(molecule, l);
11461326 int moA = this->GetActiveVirIndex(molecule, l);
1147- for(int mu=0; mu<molecule.GetTotalNumberAOs(); mu++){
1148- for(int nu=0; nu<molecule.GetTotalNumberAOs(); nu++){
1149- temp += (-1.0*fockMatrix[moI][mu]*fockMatrix[moI][nu] + fockMatrix[moA][mu]*fockMatrix[moA][nu])
1150- *(cartesianMatrix[mu][nu][axis] - molecule.GetXyzCOC()[axis]*overlapAOs[mu][nu]);
1327+ for(int mu=0; mu<totalNumberAOs; mu++){
1328+ for(int nu=0; nu<totalNumberAOs; nu++){
1329+ temp = (-1.0*fockMatrix[moI][mu]*fockMatrix[moI][nu] + fockMatrix[moA][mu]*fockMatrix[moA][nu]);
1330+ tempX += temp*(cartesianMatrix[XAxis][mu][nu] - xyzCOC[XAxis]*overlapAOs[mu][nu]);
1331+ tempY += temp*(cartesianMatrix[YAxis][mu][nu] - xyzCOC[YAxis]*overlapAOs[mu][nu]);
1332+ tempZ += temp*(cartesianMatrix[ZAxis][mu][nu] - xyzCOC[ZAxis]*overlapAOs[mu][nu]);
11511333 }
11521334 }
1153- value += matrixCIS[from-1][l]*matrixCIS[to-1][l]*temp;
1335+ temp = matrixCIS[from-1][l]*matrixCIS[to-1][l];
1336+ valueX += temp*tempX;
1337+ valueY += temp*tempY;
1338+ valueZ += temp*tempZ;
11541339 }
11551340 catch(MolDSException ex){
11561341 #pragma omp critical
@@ -1161,25 +1346,34 @@ double ZindoS::GetElectronicTransitionDipoleMoment(int to, int from, CartesianTy
11611346 if(!ompErrors.str().empty()){
11621347 throw MolDSException(ompErrors.str());
11631348 }
1164- return value;
1349+ transitionDipoleMoment[XAxis] = valueX;
1350+ transitionDipoleMoment[YAxis] = valueY;
1351+ transitionDipoleMoment[ZAxis] = valueZ;
11651352 }
11661353 else if(from == groundState && to != groundState){
11671354 // transition dipole moment from the ground to excited states
1168-#pragma omp parallel for reduction(+:value) schedule(auto)
1355+#pragma omp parallel for reduction(+:valueX,valueY,valueZ) schedule(auto)
11691356 for(int l=0; l<this->matrixCISdimension; l++){
11701357 try{
1171- double temp = 0.0;
1358+ double temp = 0.0;
1359+ double tempX = 0.0;
1360+ double tempY = 0.0;
1361+ double tempZ = 0.0;
11721362 // single excitation from I-th (occupied)MO to A-th (virtual)MO
11731363 int moI = this->GetActiveOccIndex(molecule, l);
11741364 int moA = this->GetActiveVirIndex(molecule, l);
1175- for(int mu=0; mu<molecule.GetTotalNumberAOs(); mu++){
1176- for(int nu=0; nu<molecule.GetTotalNumberAOs(); nu++){
1177- temp += fockMatrix[moA][mu]
1178- *(cartesianMatrix[mu][nu][axis] - molecule.GetXyzCOC()[axis]*overlapAOs[mu][nu])
1179- *fockMatrix[moI][nu];
1365+ for(int mu=0; mu<totalNumberAOs; mu++){
1366+ for(int nu=0; nu<totalNumberAOs; nu++){
1367+ temp = fockMatrix[moA][mu]*fockMatrix[moI][nu];
1368+ tempX += temp*(cartesianMatrix[XAxis][mu][nu] - xyzCOC[XAxis]*overlapAOs[mu][nu]);
1369+ tempY += temp*(cartesianMatrix[YAxis][mu][nu] - xyzCOC[YAxis]*overlapAOs[mu][nu]);
1370+ tempZ += temp*(cartesianMatrix[ZAxis][mu][nu] - xyzCOC[ZAxis]*overlapAOs[mu][nu]);
11801371 }
11811372 }
1182- value += this->matrixCIS[to-1][l]*sqrt(2.0)*temp;
1373+ temp = this->matrixCIS[to-1][l]*sqrt(2.0);
1374+ valueX += temp*tempX;
1375+ valueY += temp*tempY;
1376+ valueZ += temp*tempZ;
11831377 }
11841378 catch(MolDSException ex){
11851379 #pragma omp critical
@@ -1190,25 +1384,34 @@ double ZindoS::GetElectronicTransitionDipoleMoment(int to, int from, CartesianTy
11901384 if(!ompErrors.str().empty()){
11911385 throw MolDSException(ompErrors.str());
11921386 }
1193- return value;
1387+ transitionDipoleMoment[XAxis] = valueX;
1388+ transitionDipoleMoment[YAxis] = valueY;
1389+ transitionDipoleMoment[ZAxis] = valueZ;
11941390 }
11951391 else if(from != groundState && to == groundState){
11961392 // transition dipole moment from the excited to ground states
1197-#pragma omp parallel for reduction(+:value) schedule(auto)
1393+#pragma omp parallel for reduction(+:valueX,valueY,valueZ) schedule(auto)
11981394 for(int l=0; l<this->matrixCISdimension; l++){
11991395 try{
1200- double temp = 0.0;
1396+ double temp = 0.0;
1397+ double tempX = 0.0;
1398+ double tempY = 0.0;
1399+ double tempZ = 0.0;
12011400 // single excitation from I-th (occupied)MO to A-th (virtual)MO
12021401 int moI = this->GetActiveOccIndex(molecule, l);
12031402 int moA = this->GetActiveVirIndex(molecule, l);
1204- for(int mu=0; mu<molecule.GetTotalNumberAOs(); mu++){
1205- for(int nu=0; nu<molecule.GetTotalNumberAOs(); nu++){
1206- temp += fockMatrix[moI][mu]
1207- *(cartesianMatrix[mu][nu][axis] - molecule.GetXyzCOC()[axis]*overlapAOs[mu][nu])
1208- *fockMatrix[moA][nu];
1403+ for(int mu=0; mu<totalNumberAOs; mu++){
1404+ for(int nu=0; nu<totalNumberAOs; nu++){
1405+ temp = fockMatrix[moI][mu]*fockMatrix[moA][nu];
1406+ tempX += temp*(cartesianMatrix[XAxis][mu][nu] - xyzCOC[XAxis]*overlapAOs[mu][nu]);
1407+ tempY += temp*(cartesianMatrix[YAxis][mu][nu] - xyzCOC[YAxis]*overlapAOs[mu][nu]);
1408+ tempZ += temp*(cartesianMatrix[ZAxis][mu][nu] - xyzCOC[ZAxis]*overlapAOs[mu][nu]);
12091409 }
12101410 }
1211- value += matrixCIS[from-1][l]*sqrt(2.0)*temp;
1411+ temp = matrixCIS[from-1][l]*sqrt(2.0);
1412+ valueX += temp*tempX;
1413+ valueY += temp*tempY;
1414+ valueZ += temp*tempZ;
12121415 }
12131416 catch(MolDSException ex){
12141417 #pragma omp critical
@@ -1219,26 +1422,36 @@ double ZindoS::GetElectronicTransitionDipoleMoment(int to, int from, CartesianTy
12191422 if(!ompErrors.str().empty()){
12201423 throw MolDSException(ompErrors.str());
12211424 }
1222- return value;
1425+ transitionDipoleMoment[XAxis] = valueX;
1426+ transitionDipoleMoment[YAxis] = valueY;
1427+ transitionDipoleMoment[ZAxis] = valueZ;
12231428 }
12241429 }
12251430 else{
12261431 if(from != groundState){
12271432 // dipole moment of the excited state. It is needed that the dipole of ground state has been already calculated!!
1228-#pragma omp parallel for reduction(+:value) schedule(auto)
1433+#pragma omp parallel for reduction(+:valueX,valueY,valueZ) schedule(auto)
12291434 for(int l=0; l<this->matrixCISdimension; l++){
12301435 try{
1231- double temp = 0.0;
1436+ double temp = 0.0;
1437+ double tempX = 0.0;
1438+ double tempY = 0.0;
1439+ double tempZ = 0.0;
12321440 // single excitation from I-th (occupied)MO to A-th (virtual)MO
12331441 int moI = this->GetActiveOccIndex(molecule, l);
12341442 int moA = this->GetActiveVirIndex(molecule, l);
1235- for(int mu=0; mu<molecule.GetTotalNumberAOs(); mu++){
1236- for(int nu=0; nu<molecule.GetTotalNumberAOs(); nu++){
1237- temp += (-1.0*fockMatrix[moI][mu]*fockMatrix[moI][nu] + fockMatrix[moA][mu]*fockMatrix[moA][nu])
1238- *(cartesianMatrix[mu][nu][axis] - molecule.GetXyzCOC()[axis]*overlapAOs[mu][nu]);
1443+ for(int mu=0; mu<totalNumberAOs; mu++){
1444+ for(int nu=0; nu<totalNumberAOs; nu++){
1445+ temp = (-1.0*fockMatrix[moI][mu]*fockMatrix[moI][nu] + fockMatrix[moA][mu]*fockMatrix[moA][nu]);
1446+ tempX += temp*(cartesianMatrix[XAxis][mu][nu] - xyzCOC[XAxis]*overlapAOs[mu][nu]);
1447+ tempY += temp*(cartesianMatrix[YAxis][mu][nu] - xyzCOC[YAxis]*overlapAOs[mu][nu]);
1448+ tempZ += temp*(cartesianMatrix[ZAxis][mu][nu] - xyzCOC[ZAxis]*overlapAOs[mu][nu]);
12391449 }
12401450 }
1241- value += matrixCIS[from-1][l]*matrixCIS[to-1][l]*temp;
1451+ temp = matrixCIS[from-1][l]*matrixCIS[to-1][l];
1452+ valueX += temp*tempX;
1453+ valueY += temp*tempY;
1454+ valueZ += temp*tempZ;
12421455 }
12431456 catch(MolDSException ex){
12441457 #pragma omp critical
@@ -1249,22 +1462,22 @@ double ZindoS::GetElectronicTransitionDipoleMoment(int to, int from, CartesianTy
12491462 if(!ompErrors.str().empty()){
12501463 throw MolDSException(ompErrors.str());
12511464 }
1252- value += groundStateDipole[axis];
1253- return value;
1465+ transitionDipoleMoment[XAxis] = valueX + groundStateDipole[XAxis];
1466+ transitionDipoleMoment[YAxis] = valueY + groundStateDipole[YAxis];
1467+ transitionDipoleMoment[ZAxis] = valueZ + groundStateDipole[ZAxis];
12541468 }
12551469 else{
12561470 // dipole moment of the ground state
1257- value = Cndo2::GetElectronicTransitionDipoleMoment(to,
1258- from,
1259- axis,
1260- fockMatrix,
1261- matrixCIS,
1262- cartesianMatrix,
1263- molecule,
1264- orbitalElectronPopulation,
1265- overlapAOs,
1266- NULL);
1267- return value;
1471+ Cndo2::CalcElectronicTransitionDipoleMoment(transitionDipoleMoment,
1472+ to,
1473+ from,
1474+ fockMatrix,
1475+ matrixCIS,
1476+ cartesianMatrix,
1477+ molecule,
1478+ orbitalElectronPopulation,
1479+ overlapAOs,
1480+ NULL);
12681481 }
12691482 }
12701483 }
@@ -2027,273 +2240,267 @@ void ZindoS::CalcCISMatrix(double** matrixCIS) const{
20272240 this->OutputLog(this->messageStartCalcCISMatrix);
20282241 double ompStartTime = omp_get_wtime();
20292242
2030- stringstream ompErrors;
2031-#pragma omp parallel for schedule(auto)
2032- for(int k=0; k<this->matrixCISdimension; k++){
2033- try{
2034- // single excitation from I-th (occupied)MO to A-th (virtual)MO
2035- int moI = this->GetActiveOccIndex(*this->molecule, k);
2036- int moA = this->GetActiveVirIndex(*this->molecule, k);
2243+ int totalNumberAtoms = this->molecule->GetNumberAtoms();
2244+ double**** nishimotoMatagaMatrix=NULL;
2245+ try{
2246+ MallocerFreer::GetInstance()->Malloc<double>(&nishimotoMatagaMatrix, totalNumberAtoms, OrbitalType_end, totalNumberAtoms, OrbitalType_end);
2247+ this->CalcNishimotoMatagaMatrix(nishimotoMatagaMatrix, *this->molecule);
20372248
2038- for(int l=k; l<this->matrixCISdimension; l++){
2039- // single excitation from J-th (occupied)MO to B-th (virtual)MO
2040- int moJ = this->GetActiveOccIndex(*this->molecule, l);
2041- int moB = this->GetActiveVirIndex(*this->molecule, l);
2042- double value=0.0;
2043-
2044- // Fast algorithm, but this is not easy to read.
2045- // Slow algorithm is also written below.
2046- double gamma;
2047- double exchange;
2048- double coulomb;
2049- // Off diagonal term (right upper)
2050- if(k<l){
2051- for(int A=0; A<molecule->GetNumberAtoms(); A++){
2052- const Atom& atomA = *molecule->GetAtom(A);
2053- int firstAOIndexA = atomA.GetFirstAOIndex();
2054- int lastAOIndexA = atomA.GetLastAOIndex();
2249+ stringstream ompErrors;
2250+#pragma omp parallel for schedule(auto)
2251+ for(int k=0; k<this->matrixCISdimension; k++){
2252+ try{
2253+ // single excitation from I-th (occupied)MO to A-th (virtual)MO
2254+ int moI = this->GetActiveOccIndex(*this->molecule, k);
2255+ int moA = this->GetActiveVirIndex(*this->molecule, k);
2256+
2257+ for(int l=k; l<this->matrixCISdimension; l++){
2258+ // single excitation from J-th (occupied)MO to B-th (virtual)MO
2259+ int moJ = this->GetActiveOccIndex(*this->molecule, l);
2260+ int moB = this->GetActiveVirIndex(*this->molecule, l);
2261+
2262+ // Fast algorithm, but this is not easy to read. Slow algorithm is also written below.
2263+ if(k<l){
2264+ // Off diagonal term (right upper)
2265+ matrixCIS[k][l] = this->GetCISOffDiagElement(nishimotoMatagaMatrix, *this->molecule, this->fockMatrix, moI, moA, moJ, moB);
2266+ }
2267+ else if(k==l){
2268+ // Diagonal term
2269+ matrixCIS[k][l] = this->GetCISDiagElement(energiesMO, nishimotoMatagaMatrix, *this->molecule, this->fockMatrix, moI, moA);
2270+ }
2271+ // End of the fast algorith.
2272+
2273+ /*// Slow algorith, but this is easy to read. Fast altorithm is also written above.
2274+ double value=0.0;
2275+ value = 2.0*this->GetMolecularIntegralElement(moA, moI, moJ, moB,
2276+ *this->molecule,
2277+ this->fockMatrix,
2278+ NULL)
2279+ -this->GetMolecularIntegralElement(moA, moB, moI, moJ,
2280+ *this->molecule,
2281+ this->fockMatrix,
2282+ NULL);
2283+ if(k==l){
2284+ value += this->energiesMO[moA] - this->energiesMO[moI];
2285+ }
2286+ matrixCIS[k][l] = value;
2287+ // End of the slow algorith. */
2288+ }
2289+ }
2290+ catch(MolDSException ex){
2291+#pragma omp critical
2292+ ompErrors << ex.what() << endl ;
2293+ }
2294+ } // end of k-loop
2295+ // Exception throwing for omp-region
2296+ if(!ompErrors.str().empty()){
2297+ throw MolDSException(ompErrors.str());
2298+ }
2299+ }
2300+ catch(MolDSException ex){
2301+ MallocerFreer::GetInstance()->Free<double>(&nishimotoMatagaMatrix, totalNumberAtoms, OrbitalType_end, totalNumberAtoms, OrbitalType_end);
2302+ throw ex;
2303+ }
2304+ MallocerFreer::GetInstance()->Free<double>(&nishimotoMatagaMatrix, totalNumberAtoms, OrbitalType_end, totalNumberAtoms, OrbitalType_end);
2305+ double ompEndTime = omp_get_wtime();
2306+ this->OutputLog(boost::format("%s%lf%s\n%s") % this->messageOmpElapsedTimeCalcCISMarix.c_str()
2307+ % (ompEndTime - ompStartTime)
2308+ % this->messageUnitSec.c_str()
2309+ % this->messageDoneCalcCISMatrix.c_str() );
2310+}
20552311
2056- for(int mu=firstAOIndexA; mu<=lastAOIndexA; mu++){
2057- OrbitalType orbitalMu = atomA.GetValence(mu-firstAOIndexA);
2312+double ZindoS::GetCISDiagElement(double const* energiesMO,
2313+ double const* const* const* const* nishimotoMatagaMatrix,
2314+ const MolDS_base::Molecule& molecule,
2315+ double const* const* fockMatrix,
2316+ int moI,
2317+ int moA) const{
2318+ double value = energiesMO[moA] - energiesMO[moI];
2319+ double gamma = 0.0;
2320+ double exchange = 0.0;
2321+ double coulomb = 0.0;
2322+ int totalNumberAtoms = molecule.GetNumberAtoms();
2323+ for(int A=0; A<totalNumberAtoms; A++){
2324+ const Atom& atomA = *molecule.GetAtom(A);
2325+ int firstAOIndexA = atomA.GetFirstAOIndex();
2326+ int lastAOIndexA = atomA.GetLastAOIndex();
20582327
2059- // CNDO term
2060- for(int B=A; B<molecule->GetNumberAtoms(); B++){
2061- const Atom& atomB = *molecule->GetAtom(B);
2062- int firstAOIndexB = atomB.GetFirstAOIndex();
2063- int lastAOIndexB = atomB.GetLastAOIndex();
2064-
2065- for(int nu=firstAOIndexB; nu<=lastAOIndexB; nu++){
2066- OrbitalType orbitalNu = atomB.GetValence(nu-firstAOIndexB);
2067-
2068- if(A<B){
2069- gamma = this->GetNishimotoMatagaTwoEleInt(atomA,
2070- orbitalMu,
2071- atomB,
2072- orbitalNu);
2073- value += 2.0*gamma*fockMatrix[moA][mu]
2074- *fockMatrix[moI][mu]
2075- *fockMatrix[moJ][nu]
2076- *fockMatrix[moB][nu];
2077- value -= gamma*fockMatrix[moA][mu]
2078- *fockMatrix[moB][mu]
2079- *fockMatrix[moI][nu]
2080- *fockMatrix[moJ][nu];
2081- value += 2.0*gamma*fockMatrix[moA][nu]
2082- *fockMatrix[moI][nu]
2083- *fockMatrix[moJ][mu]
2084- *fockMatrix[moB][mu];
2085- value -= gamma*fockMatrix[moA][nu]
2086- *fockMatrix[moB][nu]
2087- *fockMatrix[moI][mu]
2088- *fockMatrix[moJ][mu];
2089- }
2090- else{
2091- gamma = atomA.GetZindoF0ss();
2092- value += 2.0*gamma*fockMatrix[moA][mu]
2093- *fockMatrix[moI][mu]
2094- *fockMatrix[moJ][nu]
2095- *fockMatrix[moB][nu];
2096- value -= gamma*fockMatrix[moA][mu]
2097- *fockMatrix[moB][mu]
2098- *fockMatrix[moI][nu]
2099- *fockMatrix[moJ][nu];
2100- }
2101- }
2102- }
2328+ for(int mu=firstAOIndexA; mu<=lastAOIndexA; mu++){
2329+ OrbitalType orbitalMu = atomA.GetValence(mu-firstAOIndexA);
2330+ double tmp1 = fockMatrix[moA][mu]*fockMatrix[moI][mu];
2331+ double tmp2 = fockMatrix[moI][mu]*fockMatrix[moI][mu];
2332+ double tmp3 = fockMatrix[moA][mu]*fockMatrix[moA][mu];
21032333
2104- // Aditional term for INDO or ZIND/S, see Eq. (10) in [RZ_1973]
2105- for(int nu=firstAOIndexA; nu<=lastAOIndexA; nu++){
2106- OrbitalType orbitalNu = atomA.GetValence(nu-firstAOIndexA);
2107-
2108- if(mu!=nu){
2109- exchange = this->GetExchangeInt(orbitalMu, orbitalNu, atomA);
2110- value += 2.0*exchange*fockMatrix[moA][mu]
2111- *fockMatrix[moI][nu]
2112- *fockMatrix[moJ][nu]
2113- *fockMatrix[moB][mu];
2114- value += 2.0*exchange*fockMatrix[moA][mu]
2115- *fockMatrix[moI][nu]
2116- *fockMatrix[moJ][mu]
2117- *fockMatrix[moB][nu];
2118- value -= exchange*fockMatrix[moA][mu]
2119- *fockMatrix[moB][nu]
2120- *fockMatrix[moI][nu]
2121- *fockMatrix[moJ][mu];
2122- value -= exchange*fockMatrix[moA][mu]
2123- *fockMatrix[moB][nu]
2124- *fockMatrix[moI][mu]
2125- *fockMatrix[moJ][nu];
2126- }
2334+ // CNDO term
2335+ for(int B=A; B<totalNumberAtoms; B++){
2336+ const Atom& atomB = *molecule.GetAtom(B);
2337+ int firstAOIndexB = atomB.GetFirstAOIndex();
2338+ int lastAOIndexB = atomB.GetLastAOIndex();
21272339
2128- coulomb = this->GetCoulombInt(orbitalMu, orbitalNu, atomA);
2340+ for(int nu=firstAOIndexB; nu<=lastAOIndexB; nu++){
2341+ OrbitalType orbitalNu = atomB.GetValence(nu-firstAOIndexB);
21292342
2130- if( (orbitalMu == s || orbitalMu == px || orbitalMu == py || orbitalMu == pz) &&
2131- (orbitalNu == s || orbitalNu == px || orbitalNu == py || orbitalNu == pz) ){
2132- gamma = atomA.GetZindoF0ss();
2133- }
2134- else{
2135- stringstream ss;
2136- ss << this->errorMessageCalcCISMatrix;
2137- ss << this->errorMessageAtomType << AtomTypeStr(atomA.GetAtomType()) << "\n";
2138- ss << this->errorMessageOrbitalType << OrbitalTypeStr(orbitalMu) << "\n";
2139- ss << this->errorMessageOrbitalType << OrbitalTypeStr(orbitalNu) << "\n";
2140-#pragma omp critical
2141- ompErrors << ss.str() << endl ;
2142- }
2143-
2144- value += 2.0*(coulomb-gamma)*fockMatrix[moA][mu]
2145- *fockMatrix[moI][mu]
2146- *fockMatrix[moJ][nu]
2147- *fockMatrix[moB][nu];
2148- value -= (coulomb-gamma)*fockMatrix[moA][mu]
2149- *fockMatrix[moB][mu]
2150- *fockMatrix[moI][nu]
2151- *fockMatrix[moJ][nu];
2152- }
2153- }
2343+ if(A<B){
2344+ gamma = nishimotoMatagaMatrix[A][orbitalMu][B][orbitalNu];
2345+ value += 4.0*gamma*tmp1
2346+ *fockMatrix[moA][nu]
2347+ *fockMatrix[moI][nu];
2348+ value -= gamma*tmp2
2349+ *fockMatrix[moA][nu]
2350+ *fockMatrix[moA][nu];
2351+ value -= gamma*tmp3
2352+ *fockMatrix[moI][nu]
2353+ *fockMatrix[moI][nu];
21542354 }
2355+ else{
2356+ gamma = atomA.GetZindoF0ss();
2357+ value += 2.0*gamma*tmp1
2358+ *fockMatrix[moA][nu]
2359+ *fockMatrix[moI][nu];
2360+ value -= gamma*tmp2
2361+ *fockMatrix[moA][nu]
2362+ *fockMatrix[moA][nu];
2363+ }
21552364 }
2156- // Diagonal term
2157- else if(k==l){
2158- value = this->energiesMO[moA] - this->energiesMO[moI];
2159- for(int A=0; A<molecule->GetNumberAtoms(); A++){
2160- const Atom& atomA = *molecule->GetAtom(A);
2161- int firstAOIndexA = atomA.GetFirstAOIndex();
2162- int lastAOIndexA = atomA.GetLastAOIndex();
2365+ }
21632366
2164- for(int mu=firstAOIndexA; mu<=lastAOIndexA; mu++){
2165- OrbitalType orbitalMu = atomA.GetValence(mu-firstAOIndexA);
2367+ //Aditional term for INDO or ZIND/S, see Eq. (10) in [RZ_1973]
2368+ for(int nu=firstAOIndexA; nu<=lastAOIndexA; nu++){
2369+ OrbitalType orbitalNu = atomA.GetValence(nu-firstAOIndexA);
21662370
2167- // CNDO term
2168- for(int B=A; B<molecule->GetNumberAtoms(); B++){
2169- const Atom& atomB = *molecule->GetAtom(B);
2170- int firstAOIndexB = atomB.GetFirstAOIndex();
2171- int lastAOIndexB = atomB.GetLastAOIndex();
2172-
2173- for(int nu=firstAOIndexB; nu<=lastAOIndexB; nu++){
2174- OrbitalType orbitalNu = atomB.GetValence(nu-firstAOIndexB);
2175-
2176- if(A<B){
2177- gamma = this->GetNishimotoMatagaTwoEleInt(atomA,
2178- orbitalMu,
2179- atomB,
2180- orbitalNu);
2181- value += 2.0*gamma*fockMatrix[moI][mu]
2182- *fockMatrix[moA][mu]
2183- *fockMatrix[moA][nu]
2184- *fockMatrix[moI][nu];
2185- value -= gamma*fockMatrix[moI][mu]
2186- *fockMatrix[moI][mu]
2187- *fockMatrix[moA][nu]
2188- *fockMatrix[moA][nu];
2189- value += 2.0*gamma*fockMatrix[moI][nu]
2190- *fockMatrix[moA][nu]
2191- *fockMatrix[moA][mu]
2192- *fockMatrix[moI][mu];
2193- value -= gamma*fockMatrix[moI][nu]
2194- *fockMatrix[moI][nu]
2195- *fockMatrix[moA][mu]
2196- *fockMatrix[moA][mu];
2197- }
2198- else{
2199- gamma = atomA.GetZindoF0ss();
2200- value += 2.0*gamma*fockMatrix[moI][mu]
2201- *fockMatrix[moA][mu]
2202- *fockMatrix[moA][nu]
2203- *fockMatrix[moI][nu];
2204- value -= gamma*fockMatrix[moI][mu]
2205- *fockMatrix[moI][mu]
2206- *fockMatrix[moA][nu]
2207- *fockMatrix[moA][nu];
2208- }
2209- }
2210- }
2371+ if(mu!=nu){
2372+ exchange = this->GetExchangeInt(orbitalMu, orbitalNu, atomA);
2373+ value += 2.0*exchange*tmp2
2374+ *fockMatrix[moA][nu]
2375+ *fockMatrix[moA][nu];
2376+ }
22112377
2212- // Aditional term for INDO or ZIND/S, see Eq. (10) in [RZ_1973]
2213- for(int nu=firstAOIndexA; nu<=lastAOIndexA; nu++){
2214- OrbitalType orbitalNu = atomA.GetValence(nu-firstAOIndexA);
2215-
2216- if(mu!=nu){
2217- exchange = this->GetExchangeInt(orbitalMu, orbitalNu, atomA);
2218- value += 2.0*exchange*fockMatrix[moI][mu]
2219- *fockMatrix[moA][nu]
2220- *fockMatrix[moA][nu]
2221- *fockMatrix[moI][mu];
2222- value += 2.0*exchange*fockMatrix[moI][mu]
2223- *fockMatrix[moA][nu]
2224- *fockMatrix[moA][mu]
2225- *fockMatrix[moI][nu];
2226- value -= exchange*fockMatrix[moI][mu]
2227- *fockMatrix[moI][nu]
2228- *fockMatrix[moA][nu]
2229- *fockMatrix[moA][mu];
2230- value -= exchange*fockMatrix[moI][mu]
2231- *fockMatrix[moI][nu]
2232- *fockMatrix[moA][mu]
2233- *fockMatrix[moA][nu];
2234- }
2378+ coulomb = this->GetCoulombInt(orbitalMu, orbitalNu, atomA);
2379+
2380+ if( (orbitalMu == s || orbitalMu == px || orbitalMu == py || orbitalMu == pz) &&
2381+ (orbitalNu == s || orbitalNu == px || orbitalNu == py || orbitalNu == pz) ){
2382+ gamma = atomA.GetZindoF0ss();
2383+ }
2384+ else{
2385+ stringstream ss;
2386+ ss << this->errorMessageCalcCISMatrix;
2387+ ss << this->errorMessageAtomType << AtomTypeStr(atomA.GetAtomType()) << "\n";
2388+ ss << this->errorMessageOrbitalType << OrbitalTypeStr(orbitalMu) << "\n";
2389+ ss << this->errorMessageOrbitalType << OrbitalTypeStr(orbitalNu) << "\n";
2390+ throw MolDSException(ss.str());
2391+ }
2392+ value += 2.0*(coulomb-gamma)*tmp1
2393+ *fockMatrix[moA][nu]
2394+ *fockMatrix[moI][nu];
2395+ value -= (coulomb-gamma)*tmp2
2396+ *fockMatrix[moA][nu]
2397+ *fockMatrix[moA][nu];
2398+ }
2399+ }
2400+ }
2401+ return value;
2402+}
22352403
2236- coulomb = this->GetCoulombInt(orbitalMu, orbitalNu, atomA);
2404+double ZindoS::GetCISOffDiagElement(double const* const* const* const* nishimotoMatagaMatrix,
2405+ const MolDS_base::Molecule& molecule,
2406+ double const* const* fockMatrix,
2407+ int moI,
2408+ int moA,
2409+ int moJ,
2410+ int moB) const{
2411+ double value = 0.0;
2412+ double gamma = 0.0;
2413+ double exchange = 0.0;
2414+ double coulomb = 0.0;
2415+ int totalNumberAtoms = molecule.GetNumberAtoms();
2416+ for(int A=0; A<totalNumberAtoms; A++){
2417+ const Atom& atomA = *molecule.GetAtom(A);
2418+ int firstAOIndexA = atomA.GetFirstAOIndex();
2419+ int lastAOIndexA = atomA.GetLastAOIndex();
22372420
2238- if( (orbitalMu == s || orbitalMu == px || orbitalMu == py || orbitalMu == pz) &&
2239- (orbitalNu == s || orbitalNu == px || orbitalNu == py || orbitalNu == pz) ){
2240- gamma = atomA.GetZindoF0ss();
2241- }
2242- else{
2243- stringstream ss;
2244- ss << this->errorMessageCalcCISMatrix;
2245- ss << this->errorMessageAtomType << AtomTypeStr(atomA.GetAtomType()) << "\n";
2246- ss << this->errorMessageOrbitalType << OrbitalTypeStr(orbitalMu) << "\n";
2247- ss << this->errorMessageOrbitalType << OrbitalTypeStr(orbitalNu) << "\n";
2248-#pragma omp critical
2249- ompErrors << ss.str() << endl ;
2250- }
2251-
2252- value += 2.0*(coulomb-gamma)*fockMatrix[moI][mu]
2253- *fockMatrix[moA][mu]
2254- *fockMatrix[moA][nu]
2255- *fockMatrix[moI][nu];
2256- value -= (coulomb-gamma)*fockMatrix[moI][mu]
2257- *fockMatrix[moI][mu]
2258- *fockMatrix[moA][nu]
2259- *fockMatrix[moA][nu];
2260- }
2261- }
2421+ for(int mu=firstAOIndexA; mu<=lastAOIndexA; mu++){
2422+ OrbitalType orbitalMu = atomA.GetValence(mu-firstAOIndexA);
2423+ double tmp1 = fockMatrix[moA][mu]*fockMatrix[moI][mu];
2424+ double tmp2 = fockMatrix[moA][mu]*fockMatrix[moB][mu];
2425+ double tmp3 = fockMatrix[moJ][mu]*fockMatrix[moB][mu];
2426+ double tmp4 = fockMatrix[moI][mu]*fockMatrix[moJ][mu];
2427+
2428+ // CNDO term
2429+ for(int B=A; B<totalNumberAtoms; B++){
2430+ const Atom& atomB = *molecule.GetAtom(B);
2431+ int firstAOIndexB = atomB.GetFirstAOIndex();
2432+ int lastAOIndexB = atomB.GetLastAOIndex();
2433+ for(int nu=firstAOIndexB; nu<=lastAOIndexB; nu++){
2434+ OrbitalType orbitalNu = atomB.GetValence(nu-firstAOIndexB);
2435+
2436+ if(A<B){
2437+ gamma = nishimotoMatagaMatrix[A][orbitalMu][B][orbitalNu];
2438+ value += 2.0*gamma*tmp1
2439+ *fockMatrix[moJ][nu]
2440+ *fockMatrix[moB][nu];
2441+ value -= gamma*tmp2
2442+ *fockMatrix[moI][nu]
2443+ *fockMatrix[moJ][nu];
2444+ value += 2.0*gamma*tmp3
2445+ *fockMatrix[moA][nu]
2446+ *fockMatrix[moI][nu];
2447+ value -= gamma*tmp4
2448+ *fockMatrix[moA][nu]
2449+ *fockMatrix[moB][nu];
22622450 }
2451+ else{
2452+ gamma = atomA.GetZindoF0ss();
2453+ value += 2.0*gamma*tmp1
2454+ *fockMatrix[moJ][nu]
2455+ *fockMatrix[moB][nu];
2456+ value -= gamma*tmp2
2457+ *fockMatrix[moI][nu]
2458+ *fockMatrix[moJ][nu];
2459+ }
22632460 }
2264- // End of the fast algorith.
2265- /*
2266- // Slow algorith, but this is easy to read. Fast altorithm is also written above.
2267- value = 2.0*this->GetMolecularIntegralElement(moA, moI, moJ, moB,
2268- this->molecule,
2269- this->fockMatrix,
2270- NULL)
2271- -this->GetMolecularIntegralElement(moA, moB, moI, moJ,
2272- this->molecule,
2273- this->fockMatrix,
2274- NULL);
2275- if(k==l){
2276- value += this->energiesMO[moA] - this->energiesMO[moI];
2461+ }
2462+
2463+ // Aditional term for INDO or ZIND/S, see Eq. (10) in [RZ_1973]
2464+ double tmp5 = fockMatrix[moA][mu]*fockMatrix[moB][mu];
2465+ double tmp6 = fockMatrix[moA][mu]*fockMatrix[moJ][mu];
2466+ double tmp7 = fockMatrix[moA][mu]*fockMatrix[moI][mu];
2467+ for(int nu=firstAOIndexA; nu<=lastAOIndexA; nu++){
2468+ OrbitalType orbitalNu = atomA.GetValence(nu-firstAOIndexA);
2469+
2470+ if(mu!=nu){
2471+ exchange = this->GetExchangeInt(orbitalMu, orbitalNu, atomA);
2472+ value += 2.0*exchange
2473+ *(tmp5*fockMatrix[moJ][nu] + tmp6*fockMatrix[moB][nu])
2474+ *fockMatrix[moI][nu];
2475+ value -= exchange
2476+ *(tmp6*fockMatrix[moI][nu] + tmp7*fockMatrix[moJ][nu])
2477+ *fockMatrix[moB][nu];
2478+ }
2479+
2480+ coulomb = this->GetCoulombInt(orbitalMu, orbitalNu, atomA);
2481+
2482+ if( (orbitalMu == s || orbitalMu == px || orbitalMu == py || orbitalMu == pz) &&
2483+ (orbitalNu == s || orbitalNu == px || orbitalNu == py || orbitalNu == pz) ){
2484+ gamma = atomA.GetZindoF0ss();
22772485 }
2278- // End of the slow algorith.
2279- */
2280- matrixCIS[k][l] = value;
2486+ else{
2487+ stringstream ss;
2488+ ss << this->errorMessageCalcCISMatrix;
2489+ ss << this->errorMessageAtomType << AtomTypeStr(atomA.GetAtomType()) << "\n";
2490+ ss << this->errorMessageOrbitalType << OrbitalTypeStr(orbitalMu) << "\n";
2491+ ss << this->errorMessageOrbitalType << OrbitalTypeStr(orbitalNu) << "\n";
2492+ throw MolDSException(ss.str());
2493+ }
2494+ value += 2.0*(coulomb-gamma)*tmp7
2495+ *fockMatrix[moJ][nu]
2496+ *fockMatrix[moB][nu];
2497+ value -= (coulomb-gamma)*tmp5
2498+ *fockMatrix[moI][nu]
2499+ *fockMatrix[moJ][nu];
22812500 }
22822501 }
2283- catch(MolDSException ex){
2284-#pragma omp critical
2285- ompErrors << ex.what() << endl ;
2286- }
2287- }
2288- // Exception throwing for omp-region
2289- if(!ompErrors.str().empty()){
2290- throw MolDSException(ompErrors.str());
22912502 }
2292- double ompEndTime = omp_get_wtime();
2293- this->OutputLog(boost::format("%s%lf%s\n%s") % this->messageOmpElapsedTimeCalcCISMarix.c_str()
2294- % (ompEndTime - ompStartTime)
2295- % this->messageUnitSec.c_str()
2296- % this->messageDoneCalcCISMatrix.c_str() );
2503+ return value;
22972504 }
22982505
22992506 void ZindoS::CheckMatrixForce(const vector<int>& elecStates){
@@ -2372,6 +2579,7 @@ void ZindoS::CalcForce(const vector<int>& elecStates){
23722579 const Atom& atomB = *molecule->GetAtom(b);
23732580 int firstAOIndexB = atomB.GetFirstAOIndex();
23742581 int lastAOIndexB = atomB.GetLastAOIndex();
2582+ double rAB = this->molecule->GetDistanceAtoms(atomA, atomB);
23752583
23762584 // calc. first derivative of overlapAOs.
23772585 this->CalcDiatomicOverlapAOs1stDerivatives(diatomicOverlapAOs1stDerivs, atomA, atomB);
@@ -2389,7 +2597,7 @@ void ZindoS::CalcForce(const vector<int>& elecStates){
23892597 +atomB.GetCoreCharge()
23902598 *atomicElectronPopulation[a])
23912599 *this->GetNishimotoMatagaTwoEleInt1stDerivative(
2392- atomA, s, atomB, s, (CartesianType)i);
2600+ atomA, s, atomB, s, rAB, static_cast<CartesianType>(i));
23932601 }
23942602 for(int mu=firstAOIndexA; mu<=lastAOIndexA; mu++){
23952603 OrbitalType orbitalMu = atomA.GetValence(mu-firstAOIndexA);
@@ -2408,7 +2616,8 @@ void ZindoS::CalcForce(const vector<int>& elecStates){
24082616 -0.5*pow(this->orbitalElectronPopulation[mu][nu],2.0))
24092617 *this->GetNishimotoMatagaTwoEleInt1stDerivative(
24102618 atomA, orbitalMu, atomB, orbitalNu,
2411- (CartesianType)i);
2619+ rAB,
2620+ static_cast<CartesianType>(i));
24122621 }
24132622 }
24142623 }
--- a/src/zindo/ZindoS.h
+++ b/src/zindo/ZindoS.h
@@ -48,14 +48,15 @@ protected:
4848 virtual void SetMessages();
4949 virtual void SetEnableAtomTypes();
5050 virtual void CalcCISProperties();
51- virtual double GetElectronicTransitionDipoleMoment(int to, int from, MolDS_base::CartesianType axis,
52- double const* const* fockMatrix,
53- double const* const* matrixCIS,
54- double const* const* const* cartesianMatrix,
55- const MolDS_base::Molecule& molecule,
56- double const* const* orbitalElectronPopulation,
57- double const* const* overlapAOs,
58- double const* groundStateDipole) const;
51+ virtual void CalcElectronicTransitionDipoleMoment(double* transitionDipoleMoment,
52+ int to, int from,
53+ double const* const* fockMatrix,
54+ double const* const* matrixCIS,
55+ double const* const* const* cartesianMatrix,
56+ const MolDS_base::Molecule& molecule,
57+ double const* const* orbitalElectronPopulation,
58+ double const* const* overlapAOs,
59+ double const* groundStateDipole) const;
5960 virtual void CalcGammaAB(double** gammaAB, const MolDS_base::Molecule& molecule) const;
6061 virtual double GetFockDiagElement(const MolDS_base_atoms::Atom& atomA,
6162 int indexAtomA,
@@ -100,6 +101,19 @@ protected:
100101 double const* const* fockMatrix,
101102 double const* const* gammaAB) const;
102103 virtual void CalcCISMatrix(double** matrixCIS) const;
104+ double GetCISDiagElement(double const* energiesMO,
105+ double const* const* const* const* nishimotoMatagaMatrix,
106+ const MolDS_base::Molecule& molecule,
107+ double const* const* fockMatrix,
108+ int moI,
109+ int moA) const;
110+ double GetCISOffDiagElement(double const* const* const* const* nishimotoMatagaMatrix,
111+ const MolDS_base::Molecule& molecule,
112+ double const* const* fockMatrix,
113+ int moI,
114+ int moA,
115+ int moJ,
116+ int moB) const;
103117 virtual void CalcForce(const std::vector<int>& elecStates);
104118 int GetSlaterDeterminantIndex(int activeOccIndex, int activeVirIndex) const;
105119 int GetActiveOccIndex(const MolDS_base::Molecule& molecule, int matrixCISIndex) const;
@@ -157,13 +171,13 @@ private:
157171 void CalcAtomicUnpairedPopulationCIS(double*** atomicUnpairedPopulationCIS,
158172 double const* const* const* orbitalElectronPopulationCIS,
159173 const MolDS_base::Molecule& molecule) const;
160- void CalcElectronicDipoleMomentsExcitedState(double*** electronicTransitionDipoleMoments,
161- double const* const* fockMatrix,
162- double const* const* matrixCIS,
163- double const* const* const* cartesianMatrix,
164- const MolDS_base::Molecule& molecule,
165- double const* const* orbitalElectronPopulation,
166- double const* const* overlapAOs) const;
174+ void CalcElectronicDipoleMomentsExcitedStates(double*** electronicTransitionDipoleMoments,
175+ double const* const* fockMatrix,
176+ double const* const* matrixCIS,
177+ double const* const* const* cartesianMatrix,
178+ const MolDS_base::Molecule& molecule,
179+ double const* const* orbitalElectronPopulation,
180+ double const* const* overlapAOs) const;
167181 void CalcElectronicTransitionDipoleMoments(double*** electronicTransitionDipoleMoments,
168182 double const* const* fockMatrix,
169183 double const* const* matrixCIS,
@@ -175,11 +189,24 @@ private:
175189 MolDS_base::OrbitalType orbitalA,
176190 const MolDS_base_atoms::Atom& atomB,
177191 MolDS_base::OrbitalType orbitalB) const; // ref. [MN_1957] and (5a) in [AEZ_1986]
192+ double GetNishimotoMatagaTwoEleInt(const MolDS_base_atoms::Atom& atomA,
193+ MolDS_base::OrbitalType orbitalA,
194+ const MolDS_base_atoms::Atom& atomB,
195+ MolDS_base::OrbitalType orbitalB,
196+ const double rAB) const; // ref. [MN_1957] and (5a) in [AEZ_1986]
197+ double GetNishimotoMatagaTwoEleInt1stDerivative(const MolDS_base_atoms::Atom& atomA,
198+ MolDS_base::OrbitalType orbitalA,
199+ const MolDS_base_atoms::Atom& atomB,
200+ MolDS_base::OrbitalType orbitalB,
201+ MolDS_base::CartesianType axisA) const;// ref. [MN_1957] and (5a) in [AEZ_1986]
178202 double GetNishimotoMatagaTwoEleInt1stDerivative(const MolDS_base_atoms::Atom& atomA,
179203 MolDS_base::OrbitalType orbitalA,
180204 const MolDS_base_atoms::Atom& atomB,
181205 MolDS_base::OrbitalType orbitalB,
206+ const double rAB,
182207 MolDS_base::CartesianType axisA) const;// ref. [MN_1957] and (5a) in [AEZ_1986]
208+ void CalcNishimotoMatagaMatrix(double**** nishimotoMatagaMatrix,
209+ const MolDS_base::Molecule& molecule) const;
183210 void CalcRitzVector(double* ritzVector,
184211 double const* const* expansionVectors,
185212 double const* const* interactionMatrix,
--- a/test/c2h6_pm3_directCIS_singlet.dat
+++ b/test/c2h6_pm3_directCIS_singlet.dat
@@ -1,6 +1,6 @@
11
22
3- >>>>> Welcome to the MolDS world at 2013/1/23(Wed.) 7:0:44 <<<<<
3+ >>>>> Welcome to the MolDS world at 2013/1/27(Sun.) 15:14:52 <<<<<
44
55
66 ********** START: Parse input **********
@@ -53,28 +53,29 @@ Input terms:
5353 theory | pm3 | theory_end | scf | max_iter | 50 | rms_density | 0.000001 | damping_thresh | 1.0 |
5454 damping_weight | 0.0 | diis_num_error_vect | 5 | diis_start_error | 0.1 | diis_end_error | 0.00000002 | scf_end | cis |
5555 davidson | no | active_occ | 7 | active_vir | 7 | nstates | 49 | mulliken | 3 |
56-mulliken | 100 | mulliken | 20 | cis_end | geometry | c | 0.0000 | 0.0200 | 0.0000 |
57-c | 1.4938 | -0.0150 | 0.0020 | h | -0.3500 | 1.0411 | 0.0010 | h | -0.3681 |
58--0.5205 | -0.9200 | h | -0.3700 | -0.5208 | 0.9016 | h | 1.8519 | 0.5200 | -0.9007 |
59-h | 1.8300 | 0.5240 | 0.9100 | h | 1.8600 | -1.0401 | 0.0000 | geometry_end |
56+mulliken | 100 | mulliken | 20 | unpaired_electron_population | yes | cis_end | geometry | c | 0.0000 |
57+0.0200 | 0.0000 | c | 1.4938 | -0.0150 | 0.0020 | h | -0.3500 | 1.0411 | 0.0010 |
58+h | -0.3681 | -0.5205 | -0.9200 | h | -0.3700 | -0.5208 | 0.9016 | h | 1.8519 |
59+0.5200 | -0.9007 | h | 1.8300 | 0.5240 | 0.9100 | h | 1.8600 | -1.0401 | 0.0000 |
60+geometry_end |
6061
6162 ********** DONE: Parse input ***********
6263
6364
6465 ********** START: PM3-SCF **********
65- SCF iter 0: RMS density = 5.291502622129180 DIIS error = 0.000000e+00
66- SCF iter 1: RMS density = 1.910456125626944 DIIS error = 0.000000e+00
67- SCF iter 2: RMS density = 1.044203238495391 DIIS error = 3.872759e-01
68- SCF iter 3: RMS density = 0.569275110921829 DIIS error = 2.820935e-01
66+ SCF iter 0: RMS density = 5.291502622129181 DIIS error = 0.000000e+00
67+ SCF iter 1: RMS density = 1.910456125626941 DIIS error = 0.000000e+00
68+ SCF iter 2: RMS density = 1.044203238495393 DIIS error = 3.872759e-01
69+ SCF iter 3: RMS density = 0.569275110921830 DIIS error = 2.820935e-01
6970 SCF iter 4: RMS density = 0.308641545774631 DIIS error = 1.728758e-01
70- SCF iter 5: RMS density = 0.166813060251975 DIIS error = 9.584873e-02
71- SCF iter 6: RMS density = 0.000657312351891 DIIS error = 5.177961e-02 (DIIS was applied)
72- SCF iter 7: RMS density = 0.000224796079707 DIIS error = 2.374135e-04 (DIIS was applied)
73- SCF iter 8: RMS density = 0.000083564976841 DIIS error = 9.666685e-05 (DIIS was applied)
74- SCF iter 9: RMS density = 0.000026986732846 DIIS error = 3.256104e-05 (DIIS was applied)
75- SCF iter 10: RMS density = 0.000004938275825 DIIS error = 8.689524e-06 (DIIS was applied)
76- SCF iter 11: RMS density = 0.000002003884721 DIIS error = 1.920254e-06 (DIIS was applied)
77- SCF iter 12: RMS density = 0.000000169506350 DIIS error = 7.444364e-07 (DIIS was applied)
71+ SCF iter 5: RMS density = 0.166813060251973 DIIS error = 9.584873e-02
72+ SCF iter 6: RMS density = 0.000657312351887 DIIS error = 5.177961e-02 (DIIS was applied)
73+ SCF iter 7: RMS density = 0.000224796079661 DIIS error = 2.374135e-04 (DIIS was applied)
74+ SCF iter 8: RMS density = 0.000083564977008 DIIS error = 9.666685e-05 (DIIS was applied)
75+ SCF iter 9: RMS density = 0.000026986732836 DIIS error = 3.256104e-05 (DIIS was applied)
76+ SCF iter 10: RMS density = 0.000004938275875 DIIS error = 8.689524e-06 (DIIS was applied)
77+ SCF iter 11: RMS density = 0.000002003884716 DIIS error = 1.920254e-06 (DIIS was applied)
78+ SCF iter 12: RMS density = 0.000000169506349 DIIS error = 7.444364e-07 (DIIS was applied)
7879
7980
8081
@@ -123,13 +124,13 @@ h | 1.8300 | 0.5240 | 0.9100 | h | 1.8600 | -1.0401 | 0.0000 | geometry_end |
123124 Mulliken charge(SCF): 0 6 H 1.000000e+00 3.744313e-02
124125 Mulliken charge(SCF): 0 7 H 1.000000e+00 4.258006e-02
125126
126- Elapsed time(omp) for the SCF = 0.063144[s].
127+ Elapsed time(omp) for the SCF = 0.460603[s].
127128 ********** DONE: PM3-SCF **********
128129
129130
130131 ********** START: PM3-CIS **********
131132 ----------- START: Calculation of the CIS matrix -----------
132- Elapsed time(omp) for the calc. of the CIS matrix = 0.087306[s].
133+ Elapsed time(omp) for the calc. of the CIS matrix = 0.080024[s].
133134 ----------- DONE: Calculation of the CIS matrix -----------
134135
135136 ====== START: Direct-CIS =====
@@ -362,20 +363,39 @@ h | 1.8300 | 0.5240 | 0.9100 | h | 1.8600 | -1.0401 | 0.0000 | geometry_end |
362363 Mulliken charge: 20 6 H 1.000000e+00 6.650230e-02
363364 Mulliken charge: 20 7 H 1.000000e+00 -7.729498e-02
364365
365-
366- Elapsed time(omp) for the CIS = 0.229337[s].
366+ | k-th eigenstate | i-th atom | atom type | Unpaired electron population[a.u.]|
367+ Unpaired electron population: 3 0 C 1.004203e+00
368+ Unpaired electron population: 3 1 C 1.265832e+00
369+ Unpaired electron population: 3 2 H 2.440939e-01
370+ Unpaired electron population: 3 3 H 3.361993e-01
371+ Unpaired electron population: 3 4 H 2.099692e-01
372+ Unpaired electron population: 3 5 H 3.263566e-01
373+ Unpaired electron population: 3 6 H 4.841361e-01
374+ Unpaired electron population: 3 7 H 2.469543e-01
375+
376+ Unpaired electron population: 20 0 C 7.356038e-01
377+ Unpaired electron population: 20 1 C 5.615877e-01
378+ Unpaired electron population: 20 2 H 2.741903e-01
379+ Unpaired electron population: 20 3 H 1.371744e-01
380+ Unpaired electron population: 20 4 H 1.535949e-01
381+ Unpaired electron population: 20 5 H 1.006022e-01
382+ Unpaired electron population: 20 6 H 1.013346e-01
383+ Unpaired electron population: 20 7 H 2.323766e-01
384+
385+
386+ Elapsed time(omp) for the CIS = 0.219919[s].
367387 ********** DONE: PM3-CIS **********
368388
369389
370390 Summary for memory usage:
371391 Max Heap: 0.296152[MB].
372- Current Heap(Leaked): 0.000000[MB].
392+ Current Heap(Leaked): 0.000144[MB].
373393
374394
375395 >>>>> The MolDS finished normally! <<<<<
376- >>>>> CPU time: 0.3[s]. <<<<<
377- >>>>> Elapsed time: 0[s]. <<<<<
378- >>>>> Elapsed time(OMP): 0.297168[s]. <<<<<
396+ >>>>> CPU time: 0.26[s]. <<<<<
397+ >>>>> Elapsed time: 1[s]. <<<<<
398+ >>>>> Elapsed time(OMP): 0.685674[s]. <<<<<
379399 >>>>> See you. <<<<<
380400
381401
--- a/test/c2h6_pm3_directCIS_singlet.in
+++ b/test/c2h6_pm3_directCIS_singlet.in
@@ -20,6 +20,7 @@ CIS
2020 mulliken 3
2121 mulliken 100
2222 mulliken 20
23+ unpaired_electron_population yes
2324 CIS_END
2425
2526 GEOMETRY