修订版 | 5998581cb936ac699fdf1f9e987b8f72cdea22c6 (tree) |
---|---|
时间 | 2011-01-05 18:59:57 |
作者 | Mikiya Fujii <mikiya.fujii@gmai...> |
Commiter | Mikiya Fujii |
Inertia tensor is calculated.
git-svn-id: https://svn.sourceforge.jp/svnroot/molds/MolDS/trunk@34 1136aad2-a195-0410-b898-f5ea1d11b9d8
@@ -1,5 +1,30 @@ | ||
1 | -for 32 bit | |
1 | + | |
2 | +Compile: | |
3 | + for 32 bit | |
2 | 4 | $icc MolDS.cpp -lmkl_intel -lmkl_intel_thread -lmkl_core -liomp5 -lpthread |
3 | 5 | |
4 | -for 64 bit | |
6 | + for 64 bit | |
5 | 7 | $icc MolDS.cpp -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread |
8 | + | |
9 | + | |
10 | +Carring Out: | |
11 | + $./a.out < input.in | |
12 | + | |
13 | +Principal Axes (Diagonalizing the inertia tensor): | |
14 | + Write "principal-axes" in theory-directive. | |
15 | + | |
16 | + E.g. | |
17 | + THEORY | |
18 | + principal-axes | |
19 | + THEORY_END | |
20 | + | |
21 | + -options | |
22 | + option is "origin" only for setting the origin of the inertia tensor. | |
23 | + options are written in inertia-directive in angstrom unit. | |
24 | + Center of mass is used as origin when the "origin" is not set. | |
25 | + | |
26 | + E.g. | |
27 | + INERTIA | |
28 | + origin 1.2 2.3 3.4 | |
29 | + INERTIA_END | |
30 | + |
@@ -108,6 +108,17 @@ int main(){ | ||
108 | 108 | delete zindoS; |
109 | 109 | } |
110 | 110 | |
111 | + // Diagonalize Inertia Tensor | |
112 | + else if(Parameters::GetInstance()->GetCurrentTheory() == PrincipalAxes && runingNormally){ | |
113 | + try{ | |
114 | + molecule->CalcPrincipalAxes(); | |
115 | + } | |
116 | + catch(MolDSException ex){ | |
117 | + cout << ex.what() << endl; | |
118 | + runingNormally = false; | |
119 | + } | |
120 | + | |
121 | + } | |
111 | 122 | |
112 | 123 | //Free |
113 | 124 | LapackWrapper::DeleteInstance(); |
@@ -11,6 +11,7 @@ RENUMSTR_BEGIN( TheoryType, TheoryTypeStr ) | ||
11 | 11 | RENUMSTR( CNDO2, "CNDO/2" ) |
12 | 12 | RENUMSTR( INDO, "INDO" ) |
13 | 13 | RENUMSTR( ZINDOS, "ZINDO/S" ) |
14 | + RENUMSTR( PrincipalAxes, "Principal Axes" ) | |
14 | 15 | RENUMSTR( NONE, "NONE" ) |
15 | 16 | RENUMSTR( TheoryType_end, "TheoryType_end" ) |
16 | 17 | RENUMSTR_END() |
@@ -43,11 +43,15 @@ private: | ||
43 | 43 | string stringTheoryCNDO2; |
44 | 44 | string stringTheoryINDO; |
45 | 45 | string stringTheoryZINDOS; |
46 | + string stringTheoryPrincipalAxes; | |
46 | 47 | string stringTheoryNONE; |
47 | 48 | string stringScf; |
48 | 49 | string stringScfEnd; |
49 | 50 | string stringScfMaxIter; |
50 | 51 | string stringScfRmsDensity; |
52 | + string stringInertiaTensor; | |
53 | + string stringInertiaTensorEnd; | |
54 | + string stringInertiaTensorOrigin; | |
51 | 55 | void CalcMolecularBasics(Molecule* molecule); |
52 | 56 | void OutputMolecularBasics(Molecule* molecule); |
53 | 57 | void OutputScfConditions(); |
@@ -86,6 +90,10 @@ InputParser::InputParser(){ | ||
86 | 90 | this->stringTheoryCNDO2 = "cndo/2"; |
87 | 91 | this->stringTheoryINDO = "indo"; |
88 | 92 | this->stringTheoryZINDOS = "zindo/s"; |
93 | + this->stringTheoryPrincipalAxes = "principal-axes"; | |
94 | + this->stringInertiaTensor = "inertia"; | |
95 | + this->stringInertiaTensorEnd = "inertia_end"; | |
96 | + this->stringInertiaTensorOrigin = "origin"; | |
89 | 97 | this->stringTheoryNONE = "none"; |
90 | 98 | } |
91 | 99 |
@@ -159,9 +167,9 @@ void InputParser::Parse(Molecule* molecule){ | ||
159 | 167 | if(inputTerms[i].compare(this->stringGeometry) == 0){ |
160 | 168 | int j=i+1; |
161 | 169 | while(inputTerms[j].compare(this->stringGeometryEnd) != 0){ |
162 | - double x = atof(inputTerms[j+1].c_str()); | |
163 | - double y = atof(inputTerms[j+2].c_str()); | |
164 | - double z = atof(inputTerms[j+3].c_str()); | |
170 | + double x = atof(inputTerms[j+1].c_str()) * Parameters::GetInstance()->GetAngstrom2AU(); | |
171 | + double y = atof(inputTerms[j+2].c_str()) * Parameters::GetInstance()->GetAngstrom2AU(); | |
172 | + double z = atof(inputTerms[j+3].c_str()) * Parameters::GetInstance()->GetAngstrom2AU(); | |
165 | 173 | if(inputTerms[j] == "h"){ |
166 | 174 | molecule->GetAtomVect()->push_back(new Hatom(x, y, z)); |
167 | 175 | } |
@@ -198,6 +206,23 @@ void InputParser::Parse(Molecule* molecule){ | ||
198 | 206 | i = j; |
199 | 207 | } |
200 | 208 | |
209 | + // inertia tensor condition | |
210 | + if(inputTerms[i].compare(this->stringInertiaTensor) == 0){ | |
211 | + int j=i+1; | |
212 | + while(inputTerms[j].compare(this->stringInertiaTensorEnd) != 0){ | |
213 | + // origin | |
214 | + if(inputTerms[j].compare(this->stringInertiaTensorOrigin) == 0){ | |
215 | + double x = atof(inputTerms[j+1].c_str()) * Parameters::GetInstance()->GetAngstrom2AU(); | |
216 | + double y = atof(inputTerms[j+2].c_str()) * Parameters::GetInstance()->GetAngstrom2AU(); | |
217 | + double z = atof(inputTerms[j+3].c_str()) * Parameters::GetInstance()->GetAngstrom2AU(); | |
218 | + molecule->SetInertiaTensorOrigin(x, y, z); | |
219 | + j+=3; | |
220 | + } | |
221 | + j++; | |
222 | + } | |
223 | + i = j; | |
224 | + } | |
225 | + | |
201 | 226 | // theory |
202 | 227 | if(inputTerms[i].compare(this->stringTheory) == 0){ |
203 | 228 | int j=i+1; |
@@ -218,10 +243,16 @@ void InputParser::Parse(Molecule* molecule){ | ||
218 | 243 | Parameters::GetInstance()->SetCurrentTheory(ZINDOS); |
219 | 244 | } |
220 | 245 | |
246 | + // Princepal axes | |
247 | + else if(inputTerms[j].compare(this->stringTheoryPrincipalAxes) == 0){ | |
248 | + Parameters::GetInstance()->SetCurrentTheory(PrincipalAxes); | |
249 | + } | |
250 | + | |
221 | 251 | // NONE |
222 | 252 | else if(inputTerms[j].compare(this->stringTheoryNONE) == 0){ |
223 | 253 | Parameters::GetInstance()->SetCurrentTheory(NONE); |
224 | 254 | } |
255 | + | |
225 | 256 | j++; |
226 | 257 | } |
227 | 258 | i = j; |
@@ -300,6 +331,7 @@ bool InputParser::IsCommentOut(string tempStr){ | ||
300 | 331 | |
301 | 332 | } |
302 | 333 | |
334 | + | |
303 | 335 | } |
304 | 336 | #endif |
305 | 337 |
@@ -16,9 +16,12 @@ class Molecule{ | ||
16 | 16 | private: |
17 | 17 | vector<Atom*>* atomVect; |
18 | 18 | double* COMXyz; |
19 | + double* inertiaTensorOrigin; | |
19 | 20 | bool wasCalculatedCOMXyz; |
20 | 21 | int totalNumberAOs; |
21 | 22 | int totalNumberValenceElectrons; |
23 | + void CalcInertiaTensor(double** inertiaTensor); | |
24 | + void FreeInertiaTensorMoments(double** inertiaTensor, double* inertiaMoments); | |
22 | 25 | string messageTotalNumberAOs; |
23 | 26 | string messageTotalNumberAtoms; |
24 | 27 | string messageTotalNumberValenceElectrons; |
@@ -41,11 +44,14 @@ public: | ||
41 | 44 | void OutputCOMXyz(); |
42 | 45 | void OutputTotalNumberAtomsAOsValenceelectrons(); |
43 | 46 | void OutputConfiguration(); |
47 | + void SetInertiaTensorOrigin(double x, double y, double z); | |
48 | + void CalcPrincipalAxes(); | |
44 | 49 | }; |
45 | 50 | |
46 | 51 | Molecule::Molecule(){ |
47 | 52 | this->atomVect = new vector<Atom*>; |
48 | 53 | this->COMXyz = MallocerFreer::GetInstance()->MallocDoubleMatrix1d(3); |
54 | + this->inertiaTensorOrigin = NULL; | |
49 | 55 | this->wasCalculatedCOMXyz = false; |
50 | 56 | this->messageTotalNumberAOs = "\tTotal number of valence AOs: "; |
51 | 57 | this->messageTotalNumberAtoms = "\tTotal number of atoms: "; |
@@ -73,6 +79,11 @@ Molecule::~Molecule(){ | ||
73 | 79 | this->COMXyz = NULL; |
74 | 80 | //cout << "COMXyz deleted\n"; |
75 | 81 | } |
82 | + if(this->inertiaTensorOrigin != NULL){ | |
83 | + MallocerFreer::GetInstance()->FreeDoubleMatrix1d(this->inertiaTensorOrigin); | |
84 | + this->inertiaTensorOrigin = NULL; | |
85 | + //cout << "inertiaTensorOrigin deleted\n"; | |
86 | + } | |
76 | 87 | } |
77 | 88 | |
78 | 89 | vector<Atom*>* Molecule::GetAtomVect(){ |
@@ -175,6 +186,89 @@ void Molecule::OutputTotalNumberAtomsAOsValenceelectrons(){ | ||
175 | 186 | cout << this->messageTotalNumberValenceElectrons << this->totalNumberValenceElectrons << "\n\n"; |
176 | 187 | } |
177 | 188 | |
189 | +void Molecule::SetInertiaTensorOrigin(double x, double y, double z){ | |
190 | + if(this->inertiaTensorOrigin == NULL){ | |
191 | + this->inertiaTensorOrigin = MallocerFreer::GetInstance()->MallocDoubleMatrix1d(3); | |
192 | + } | |
193 | + | |
194 | + this->inertiaTensorOrigin[0] = x; | |
195 | + this->inertiaTensorOrigin[1] = y; | |
196 | + this->inertiaTensorOrigin[2] = z; | |
197 | + | |
198 | +} | |
199 | + | |
200 | +void Molecule::CalcPrincipalAxes(){ | |
201 | + | |
202 | + if(this->inertiaTensorOrigin == NULL){ | |
203 | + this->SetInertiaTensorOrigin(this->COMXyz[0], this->COMXyz[1], this->COMXyz[2]); | |
204 | + } | |
205 | + | |
206 | + double** inertiaTensor = MallocerFreer::GetInstance()->MallocDoubleMatrix2d(3, 3); | |
207 | + double* inertiaMoments = MallocerFreer::GetInstance()->MallocDoubleMatrix1d(3); | |
208 | + | |
209 | + try{ | |
210 | + this->CalcInertiaTensor(inertiaTensor); | |
211 | + | |
212 | + // ToDo: diagonalization!!!!!! | |
213 | + | |
214 | + } | |
215 | + catch(MolDSException ex){ | |
216 | + this->FreeInertiaTensorMoments(inertiaTensor, inertiaMoments); | |
217 | + throw ex; | |
218 | + } | |
219 | + | |
220 | + this->FreeInertiaTensorMoments(inertiaTensor, inertiaMoments); | |
221 | + | |
222 | +} | |
223 | + | |
224 | +void Molecule::CalcInertiaTensor(double** inertiaTensor){ | |
225 | + | |
226 | + Atom* atom; | |
227 | + double x; | |
228 | + double y; | |
229 | + double z; | |
230 | + double atomicMass; | |
231 | + for(int a=0; a<this->atomVect->size(); a++){ | |
232 | + atom = (*this->atomVect)[a]; | |
233 | + atomicMass = atom->GetAtomicMass(); | |
234 | + x = atom->GetXyz()[0] - this->inertiaTensorOrigin[0]; | |
235 | + y = atom->GetXyz()[1] - this->inertiaTensorOrigin[1]; | |
236 | + z = atom->GetXyz()[2] - this->inertiaTensorOrigin[2]; | |
237 | + | |
238 | + inertiaTensor[0][0] += atomicMass*(y*y + z*z); | |
239 | + inertiaTensor[0][1] -= atomicMass*x*y; | |
240 | + inertiaTensor[0][2] -= atomicMass*x*z; | |
241 | + | |
242 | + inertiaTensor[1][0] -= atomicMass*y*x; | |
243 | + inertiaTensor[1][1] += atomicMass*(x*x + z*z); | |
244 | + inertiaTensor[1][2] -= atomicMass*y*z; | |
245 | + | |
246 | + inertiaTensor[2][0] -= atomicMass*z*x; | |
247 | + inertiaTensor[2][1] -= atomicMass*z*y; | |
248 | + inertiaTensor[2][2] += atomicMass*(x*x + y*y); | |
249 | + | |
250 | + } | |
251 | + | |
252 | +} | |
253 | + | |
254 | +void Molecule::FreeInertiaTensorMoments(double** inertiaTensor, double* inertiaMoments){ | |
255 | + | |
256 | + if(inertiaTensor != NULL){ | |
257 | + MallocerFreer::GetInstance()->FreeDoubleMatrix2d(inertiaTensor, 3); | |
258 | + inertiaTensor = NULL; | |
259 | + //cout << "inertiaTensor deleted\n"; | |
260 | + } | |
261 | + | |
262 | + if(inertiaMoments != NULL){ | |
263 | + MallocerFreer::GetInstance()->FreeDoubleMatrix1d(inertiaMoments); | |
264 | + inertiaMoments = NULL; | |
265 | + //cout << "inertiaMoments deleted\n"; | |
266 | + } | |
267 | + | |
268 | +} | |
269 | + | |
270 | + | |
271 | + | |
178 | 272 | } |
179 | 273 | #endif |
180 | 274 |
@@ -24,6 +24,7 @@ private: | ||
24 | 24 | double eV2AU; |
25 | 25 | double angstrom2AU; |
26 | 26 | double kayser2AU; |
27 | + double gMolin2AU; | |
27 | 28 | double bondingAdjustParameterK; //see (3.79) in J. A. Pople book |
28 | 29 | TheoryType currentTheory; |
29 | 30 |
@@ -38,6 +39,7 @@ public: | ||
38 | 39 | double GetEV2AU(); |
39 | 40 | double GetAngstrom2AU(); |
40 | 41 | double GetKayser2AU(); |
42 | + double GetGMolin2AU(); | |
41 | 43 | double GetBondingAdjustParameterK(); |
42 | 44 | TheoryType GetCurrentTheory(); |
43 | 45 | void SetCurrentTheory(TheoryType theory); |
@@ -73,6 +75,7 @@ void Parameters::SetDefaultValues(){ | ||
73 | 75 | this->thresholdSCF = pow(10.0, -8.0); |
74 | 76 | this->maxIterationsSCF = 100; |
75 | 77 | this->currentTheory = CNDO2; |
78 | + this->gMolin2AU = pow(10.0,5.0)/(6.0221415*9.1095); | |
76 | 79 | } |
77 | 80 | |
78 | 81 | double Parameters::GetThresholdSCF(){ |
@@ -103,6 +106,10 @@ double Parameters::GetKayser2AU(){ | ||
103 | 106 | return this->kayser2AU; |
104 | 107 | } |
105 | 108 | |
109 | +double Parameters::GetGMolin2AU(){ | |
110 | + return this->gMolin2AU; | |
111 | +} | |
112 | + | |
106 | 113 | double Parameters::GetBondingAdjustParameterK(){ |
107 | 114 | return this->bondingAdjustParameterK; |
108 | 115 | } |
@@ -160,9 +160,9 @@ double* Atom::GetXyz(){ | ||
160 | 160 | } |
161 | 161 | |
162 | 162 | void Atom::SetXyz(double x, double y, double z){ |
163 | - xyz[0]= x * Parameters::GetInstance()->GetAngstrom2AU(); | |
164 | - xyz[1]= y * Parameters::GetInstance()->GetAngstrom2AU(); | |
165 | - xyz[2]= z * Parameters::GetInstance()->GetAngstrom2AU(); | |
163 | + xyz[0]= x; | |
164 | + xyz[1]= y; | |
165 | + xyz[2]= z; | |
166 | 166 | } |
167 | 167 | |
168 | 168 | vector<OrbitalType> Atom::GetValence(){ |
@@ -16,7 +16,7 @@ public: | ||
16 | 16 | |
17 | 17 | Catom::Catom(double x, double y, double z) : Atom(x, y, z){ |
18 | 18 | this->atomType = C; |
19 | - this->atomicMass = 12.0107; | |
19 | + this->atomicMass = 12.0107*Parameters::GetInstance()->GetGMolin2AU(); | |
20 | 20 | this->valence.push_back(s); |
21 | 21 | this->valence.push_back(py); |
22 | 22 | this->valence.push_back(pz); |
@@ -17,7 +17,7 @@ public: | ||
17 | 17 | |
18 | 18 | Hatom::Hatom(double x, double y, double z) : Atom(x, y, z){ |
19 | 19 | this->atomType = H; |
20 | - this->atomicMass = 1.00794; | |
20 | + this->atomicMass = 1.00794*Parameters::GetInstance()->GetGMolin2AU(); | |
21 | 21 | this->valence.push_back(s); |
22 | 22 | this->bondingParameter = -9.0*Parameters::GetInstance()->GetEV2AU(); |
23 | 23 | this->bondingParameterSZindo = -9.0*Parameters::GetInstance()->GetEV2AU(); |
@@ -17,7 +17,7 @@ public: | ||
17 | 17 | |
18 | 18 | Liatom::Liatom(double x, double y, double z) : Atom(x, y, z){ |
19 | 19 | this->atomType = Li; |
20 | - this->atomicMass = 6.941; | |
20 | + this->atomicMass = 6.941*Parameters::GetInstance()->GetGMolin2AU(); | |
21 | 21 | this->valence.push_back(s); |
22 | 22 | this->valence.push_back(py); |
23 | 23 | this->valence.push_back(pz); |
@@ -16,7 +16,7 @@ public: | ||
16 | 16 | |
17 | 17 | Satom::Satom(double x, double y, double z) : Atom(x, y, z){ |
18 | 18 | this->atomType = S; |
19 | - this->atomicMass = 32.066; | |
19 | + this->atomicMass = 32.066*Parameters::GetInstance()->GetGMolin2AU(); | |
20 | 20 | this->valence.push_back(s); |
21 | 21 | this->valence.push_back(py); |
22 | 22 | this->valence.push_back(pz); |
@@ -7,9 +7,15 @@ THEORY | ||
7 | 7 | //cndo/2 |
8 | 8 | //indo |
9 | 9 | //zindo/s |
10 | - none | |
10 | + //none | |
11 | + principal-axes | |
11 | 12 | THEORY_END |
12 | 13 | |
14 | +INERTIA | |
15 | + origin 1.0 2.0 3.0 | |
16 | +INERTIA_END | |
17 | + | |
18 | + | |
13 | 19 | //metane |
14 | 20 | //GEOMETRY |
15 | 21 | // C -0.37687006 0.95490165 0.00000000 |