Revision | 1843479d8400c6f31dfdab20a3081c6ba9bb2fc5 (tree) |
---|---|
Time | 2013-12-04 11:54:29 |
Author | Mikiya Fujii <mikiya.fujii@gmai...> |
Commiter | Mikiya Fujii |
Coulomb interaction between cores and EPCs is implemented. #32469
git-svn-id: https://svn.sourceforge.jp/svnroot/molds/trunk@1572 1136aad2-a195-0410-b898-f5ea1d11b9d8
@@ -339,11 +339,11 @@ HOW TO WRITE INPUT: | ||
339 | 339 | MOPLOT_END |
340 | 340 | |
341 | 341 | <Environmental Point Charge(EPC) method> |
342 | - Environmental point charge method is a simplified method of the QM/MM | |
343 | - because the environmental point changes are treated as atoms in the MM region. | |
342 | + Environmental point charge method is a simplified method of the QM/MM, | |
343 | + namely the environmental point changes are treated as atoms in the MM region. | |
344 | 344 | The differences between the QM/MM and EPC are summarized below: |
345 | 345 | - Electrostatic interaction between QM and MM region: |
346 | - QM/MM: Electrostatic interaction is mutually added to QM and MM atoms. | |
346 | + QM/MM: Electrostatic interaction may be mutually added to QM and MM atoms. | |
347 | 347 | EPC : Electrostatic field caused by the EPCs affects the QM region |
348 | 348 | although the each EPC is not affected by electrostatic field |
349 | 349 | caused by the QM atoms and other EPCs. |
@@ -351,6 +351,8 @@ HOW TO WRITE INPUT: | ||
351 | 351 | - Van der Waals interaction between QM and MM region: |
352 | 352 | QM/MM: Included. |
353 | 353 | EPC : Not included. |
354 | + In this EPC method, core-core replustion between QM and MM atoms is implemented with | |
355 | + the method I (simple coulomb interaction: qq/r) of ref [LRCL_2000]. | |
354 | 356 | This EPC method can be used with MNDO-series (MNDO, AM1, AM1-D, PM3, PM3-D, and PDDG/PM3) only. |
355 | 357 | To use this environmental point charges method, write EPC-directive. |
356 | 358 |
@@ -361,18 +363,19 @@ HOW TO WRITE INPUT: | ||
361 | 363 | |
362 | 364 | -options |
363 | 365 | "the cartesian coordinates and charge" is only prepared. |
364 | - Namely, each line should containe 4 doubles. | |
366 | + Namely, each line should containe 4 doubles and a term. | |
365 | 367 | The first three doubles are the cartesian coordinates of |
366 | 368 | each environmental point charge in angstrom unit. |
367 | - The last double is the charge in atomic unit, | |
369 | + The term is "charge". The last double following the term, "charge", | |
370 | + is the charge in atomic unit, | |
368 | 371 | e.g. -1 and 1 mean charge of an electron and a proton, respectively. |
369 | 372 | Multiple setting of the environmental point charge is approvable, of course. |
370 | 373 | |
371 | 374 | E.g. |
372 | 375 | EPC |
373 | - 0.0 0.0 0.0 -1 | |
374 | - 2.2 1.5 3.0 -1.5 | |
375 | - 0.0 2.0 5.0 0.3 | |
376 | + 0.0 0.0 0.0 charge -1 | |
377 | + 2.2 1.5 3.0 charge -1.5 | |
378 | + 0.0 2.0 5.0 charge 0.3 | |
376 | 379 | EPC_END |
377 | 380 | |
378 | 381 | <Frequencies (Normal modes analysis)> |
@@ -50,6 +50,7 @@ | ||
50 | 50 | [BFB_1997] M. A. Blanco, M. Fl{\'o}rez, and M. Bermejo, J. Mol. Struct. 419, 19 (1997) |
51 | 51 | [BB_1998] E. Besalu, J. M. Bofill, Theor. Chem. Acc. 100, 265 (1998) |
52 | 52 | [I_1998] IWANAMI-SHOTEN "IWANAMI RIKAGAKUJITEN", ISBN4-00-080090-6 (1988) |
53 | +[LRCL_2000] F. J. Luque, N. Reuter, A. Cartier, and M. F. R.-Lopez, J. Phys. Chem. A 104, 10923 (2000) | |
53 | 54 | [RCJ_2002] M. P. Repasky, J. Chandrasekhar, and W. L. Jorgensen, J. Comp. Chem. 23, 1601 (2002) |
54 | 55 | [BGRJ_2003] I. T.-Brohman, C. R. W. Guimar\~{a}es, M. P. Repasky, and W. L. Jorgensen, J. Comp. Chem. 25, 138 (2003) |
55 | 56 | [S_2004] J. J. P. Stewart, J. Mol. Model. 10, 155 (2004) |
@@ -251,8 +251,9 @@ void InputParser::SetMessages(){ | ||
251 | 251 | this->stringGeometryEnd = "geometry_end"; |
252 | 252 | |
253 | 253 | // Environmental Point Charge |
254 | - this->stringEpc = "epc"; | |
255 | - this->stringEpcEnd = "epc_end"; | |
254 | + this->stringEpc = "epc"; | |
255 | + this->stringEpcEnd = "epc_end"; | |
256 | + this->stringEpcCharge = "charge"; | |
256 | 257 | |
257 | 258 | // SCF |
258 | 259 | this->stringScf = "scf"; |
@@ -500,12 +501,16 @@ int InputParser::ParseEpcsConfiguration(Molecule* molecule, vector<string>* inpu | ||
500 | 501 | double x = atof((*inputTerms)[parseIndex+0].c_str()) * Parameters::GetInstance()->GetAngstrom2AU(); |
501 | 502 | double y = atof((*inputTerms)[parseIndex+1].c_str()) * Parameters::GetInstance()->GetAngstrom2AU(); |
502 | 503 | double z = atof((*inputTerms)[parseIndex+2].c_str()) * Parameters::GetInstance()->GetAngstrom2AU(); |
503 | - double charge = atof((*inputTerms)[parseIndex+3].c_str()); | |
504 | + parseIndex += 3; | |
505 | + double charge = 0.0; | |
506 | + if((*inputTerms)[parseIndex].compare(this->stringEpcCharge) == 0){ | |
507 | + charge = atof((*inputTerms)[parseIndex+1].c_str()); | |
508 | + parseIndex += 2; | |
509 | + } | |
504 | 510 | AtomType atomType = EPC; |
505 | 511 | int index = molecule->GetNumberEpcs(); |
506 | 512 | Atom* atom = AtomFactory::Create(atomType, index, x, y, z, charge); |
507 | 513 | molecule->AddEpc(atom); |
508 | - parseIndex += 4; | |
509 | 514 | } |
510 | 515 | return parseIndex; |
511 | 516 | } |
@@ -177,6 +177,7 @@ private: | ||
177 | 177 | // EPC |
178 | 178 | std::string stringEpc; |
179 | 179 | std::string stringEpcEnd; |
180 | + std::string stringEpcCharge; | |
180 | 181 | // SCF |
181 | 182 | std::string stringScf; |
182 | 183 | std::string stringScfEnd; |
@@ -71,9 +71,10 @@ Cndo2::Cndo2(){ | ||
71 | 71 | //protected variables |
72 | 72 | this->molecule = NULL; |
73 | 73 | this->theory = CNDO2; |
74 | - this->coreRepulsionEnergy = 0.0; | |
75 | - this->vdWCorrectionEnergy = 0.0; | |
76 | - this->matrixCISdimension = 0; | |
74 | + this->coreRepulsionEnergy = 0.0; | |
75 | + this->coreEpcCoulombEnergy = 0.0; | |
76 | + this->vdWCorrectionEnergy = 0.0; | |
77 | + this->matrixCISdimension = 0; | |
77 | 78 | this->fockMatrix = NULL; |
78 | 79 | this->energiesMO = NULL; |
79 | 80 | this->orbitalElectronPopulation = NULL; |
@@ -228,12 +229,16 @@ void Cndo2::SetMessages(){ | ||
228 | 229 | this->messageUnpairedAtoms = "\tUnpaired electron population:"; |
229 | 230 | this->messageUnpairedAtomsTitle = "\t\t\t\t| k-th eigenstate | i-th atom | atom type | Unpaired electron population[a.u.]| \n"; |
230 | 231 | this->messageElecEnergy = "\tElectronic energy(SCF):"; |
231 | - this->messageNoteElecEnergy = "\tNote that this electronic energy includes core-repulsions.\n\n"; | |
232 | - this->messageNoteElecEnergyVdW = "\tNote that this electronic energy includes core-repulsions and vdW correction.\n\n"; | |
232 | + this->messageNoteElecEnergy = "\tNote that this electronic energy includes core-repulsions.\n\n"; | |
233 | + this->messageNoteElecEnergyVdW = "\tNote that this electronic energy includes core-repulsions and vdW correction.\n\n"; | |
234 | + this->messageNoteElecEnergyEpcVdW = "\tNote that this electronic energy includes core-repulsions, core-EPC coulomb, and vdW correction.\n\n"; | |
235 | + this->messageNoteElecEnergyEpc = "\tNote that this electronic energy includes core-repulsions and core-EPC coulomb.\n\n"; | |
233 | 236 | this->messageElecEnergyTitle = "\t\t\t\t| [a.u.] | [eV] |\n"; |
234 | 237 | this->messageUnitSec = "[s]."; |
235 | 238 | this->messageCoreRepulsionTitle = "\t\t\t\t| [a.u.] | [eV] |\n"; |
236 | 239 | this->messageCoreRepulsion = "\tCore repulsion energy:"; |
240 | + this->messageCoreEpcCoulombTitle = "\t\t\t\t\t\t\t\t| [a.u.] | [eV] |\n"; | |
241 | + this->messageCoreEpcCoulomb = "\tCoulomb interaction between cores and EPCs energy:"; | |
237 | 242 | this->messageVdWCorrectionTitle = "\t\t\t\t\t\t| [a.u.] | [eV] |\n"; |
238 | 243 | this->messageVdWCorrection = "\tEmpirical van der Waals correction:"; |
239 | 244 | this->messageElectronicDipoleMomentTitle = "\t\t\t\t\t| x[a.u.] | y[a.u.] | z[a.u.] | magnitude[a.u.] |\t\t| x[debye] | y[debye] | z[debye] | magnitude[debye] |\n"; |
@@ -341,6 +346,7 @@ void Cndo2::CheckEnableAtomType(const Molecule& molecule) const{ | ||
341 | 346 | } |
342 | 347 | |
343 | 348 | void Cndo2::CalcCoreRepulsionEnergy(){ |
349 | + // interaction between atoms | |
344 | 350 | double energy = 0.0; |
345 | 351 | for(int i=0; i<this->molecule->GetNumberAtoms(); i++){ |
346 | 352 | for(int j=i+1; j<this->molecule->GetNumberAtoms(); j++){ |
@@ -348,6 +354,17 @@ void Cndo2::CalcCoreRepulsionEnergy(){ | ||
348 | 354 | } |
349 | 355 | } |
350 | 356 | this->coreRepulsionEnergy = energy; |
357 | + | |
358 | + // interaction between atoms and epcs | |
359 | + if(this->molecule->GetNumberEpcs()<=0){return;} | |
360 | + energy = 0.0; | |
361 | + for(int i=0; i<this->molecule->GetNumberAtoms(); i++){ | |
362 | + for(int j=0; j<this->molecule->GetNumberEpcs(); j++){ | |
363 | + energy += this->GetAtomCoreEpcCoulombEnergy(i, j); | |
364 | + } | |
365 | + } | |
366 | + this->coreEpcCoulombEnergy = energy; | |
367 | + | |
351 | 368 | } |
352 | 369 | |
353 | 370 | double Cndo2::GetDiatomCoreRepulsionEnergy(int indexAtomA, int indexAtomB) const{ |
@@ -357,6 +374,11 @@ double Cndo2::GetDiatomCoreRepulsionEnergy(int indexAtomA, int indexAtomB) const | ||
357 | 374 | return atomA.GetCoreCharge()*atomB.GetCoreCharge()/distance; |
358 | 375 | } |
359 | 376 | |
377 | +double Cndo2::GetAtomCoreEpcCoulombEnergy(int indexAtom, int indexEpc) const{ | |
378 | + // do nothiing | |
379 | + return 0.0; | |
380 | +} | |
381 | + | |
360 | 382 | // First derivative of diatomic core repulsion energy. |
361 | 383 | // This derivative is related to the coordinate of atomA. |
362 | 384 | double Cndo2::GetDiatomCoreRepulsion1stDerivative(int indexAtomA, int indexAtomB, |
@@ -652,12 +674,13 @@ void Cndo2::CalcSCFProperties(){ | ||
652 | 674 | this->CalcVdWCorrectionEnergy(); |
653 | 675 | } |
654 | 676 | this->CalcElecSCFEnergy(&this->elecSCFEnergy, |
655 | - *this->molecule, | |
656 | - this->energiesMO, | |
657 | - this->fockMatrix, | |
658 | - this->gammaAB, | |
659 | - this->coreRepulsionEnergy, | |
660 | - this->vdWCorrectionEnergy); | |
677 | + *this->molecule, | |
678 | + this->energiesMO, | |
679 | + this->fockMatrix, | |
680 | + this->gammaAB, | |
681 | + this->coreRepulsionEnergy, | |
682 | + this->coreEpcCoulombEnergy, | |
683 | + this->vdWCorrectionEnergy); | |
661 | 684 | this->CalcCoreDipoleMoment(this->coreDipoleMoment, *this->molecule); |
662 | 685 | this->CalcElectronicDipoleMomentGroundState(this->electronicTransitionDipoleMoments, |
663 | 686 | this->cartesianMatrix, |
@@ -990,9 +1013,15 @@ void Cndo2::OutputSCFEnergies() const{ | ||
990 | 1013 | this->OutputLog(boost::format("%s\t%e\t%e\n") % this->messageElecEnergy |
991 | 1014 | % this->elecSCFEnergy |
992 | 1015 | % (this->elecSCFEnergy/eV2AU)); |
993 | - if(Parameters::GetInstance()->RequiresVdWSCF()){ | |
1016 | + if(Parameters::GetInstance()->RequiresVdWSCF() && this->molecule->GetNumberEpcs()<=0){ | |
994 | 1017 | this->OutputLog(this->messageNoteElecEnergyVdW); |
995 | 1018 | } |
1019 | + else if(Parameters::GetInstance()->RequiresVdWSCF() && 0<this->molecule->GetNumberEpcs()){ | |
1020 | + this->OutputLog(this->messageNoteElecEnergyEpcVdW); | |
1021 | + } | |
1022 | + else if(!Parameters::GetInstance()->RequiresVdWSCF() && 0<this->molecule->GetNumberEpcs()){ | |
1023 | + this->OutputLog(this->messageNoteElecEnergyEpc); | |
1024 | + } | |
996 | 1025 | else{ |
997 | 1026 | this->OutputLog(this->messageNoteElecEnergy); |
998 | 1027 | } |
@@ -1003,6 +1032,14 @@ void Cndo2::OutputSCFEnergies() const{ | ||
1003 | 1032 | % this->coreRepulsionEnergy |
1004 | 1033 | % (this->coreRepulsionEnergy/eV2AU)); |
1005 | 1034 | |
1035 | + // output coulomb interaction between atoms and epcs | |
1036 | + if(0<this->molecule->GetNumberEpcs()){ | |
1037 | + this->OutputLog(this->messageCoreEpcCoulombTitle); | |
1038 | + this->OutputLog(boost::format("%s\t%e\t%e\n\n") % this->messageCoreEpcCoulomb | |
1039 | + % this->coreEpcCoulombEnergy | |
1040 | + % (this->coreEpcCoulombEnergy/eV2AU)); | |
1041 | + } | |
1042 | + | |
1006 | 1043 | // output van der Waals correction |
1007 | 1044 | if(Parameters::GetInstance()->RequiresVdWSCF()){ |
1008 | 1045 | this->OutputLog(this->messageVdWCorrectionTitle); |
@@ -1194,6 +1231,7 @@ void Cndo2::CalcElecSCFEnergy(double* elecSCFEnergy, | ||
1194 | 1231 | double const* const* fockMatrix, |
1195 | 1232 | double const* const* gammaAB, |
1196 | 1233 | double coreRepulsionEnergy, |
1234 | + double coreEpcCoulombEnergy, | |
1197 | 1235 | double vdWCorrectionEnergy) const{ |
1198 | 1236 | double electronicEnergy = 0.0; |
1199 | 1237 | // use density matrix for electronic energy |
@@ -1273,7 +1311,10 @@ void Cndo2::CalcElecSCFEnergy(double* elecSCFEnergy, | ||
1273 | 1311 | } |
1274 | 1312 | */ |
1275 | 1313 | |
1276 | - *elecSCFEnergy = electronicEnergy + coreRepulsionEnergy + vdWCorrectionEnergy; | |
1314 | + *elecSCFEnergy = electronicEnergy | |
1315 | + +coreRepulsionEnergy | |
1316 | + +coreEpcCoulombEnergy | |
1317 | + +vdWCorrectionEnergy; | |
1277 | 1318 | } |
1278 | 1319 | |
1279 | 1320 | void Cndo2::FreeElecEnergyMatrices(double*** fMatrix, |
@@ -94,6 +94,7 @@ protected: | ||
94 | 94 | MolDS_base::Molecule* molecule; |
95 | 95 | MolDS_base::TheoryType theory; |
96 | 96 | double coreRepulsionEnergy; |
97 | + double coreEpcCoulombEnergy; | |
97 | 98 | double vdWCorrectionEnergy; |
98 | 99 | int matrixCISdimension; |
99 | 100 | double** fockMatrix; |
@@ -132,6 +133,7 @@ protected: | ||
132 | 133 | double GetBondingAdjustParameterK(MolDS_base::ShellType shellA, |
133 | 134 | MolDS_base::ShellType shellB) const; |
134 | 135 | virtual double GetDiatomCoreRepulsionEnergy(int indexAtomA, int indexAtomB) const; |
136 | + virtual double GetAtomCoreEpcCoulombEnergy (int indexAtom, int indexEpc) const; | |
135 | 137 | virtual double GetDiatomCoreRepulsion1stDerivative(int indexAtomA, |
136 | 138 | int indexAtomB, |
137 | 139 | MolDS_base::CartesianType axisA) const; |
@@ -305,11 +307,15 @@ private: | ||
305 | 307 | std::string messageElecEnergy; |
306 | 308 | std::string messageNoteElecEnergy; |
307 | 309 | std::string messageNoteElecEnergyVdW; |
310 | + std::string messageNoteElecEnergyEpcVdW; | |
311 | + std::string messageNoteElecEnergyEpc; | |
308 | 312 | std::string messageElecEnergyTitle; |
309 | 313 | std::string messageOcc; |
310 | 314 | std::string messageUnOcc; |
311 | 315 | std::string messageCoreRepulsionTitle; |
312 | 316 | std::string messageCoreRepulsion; |
317 | + std::string messageCoreEpcCoulombTitle; | |
318 | + std::string messageCoreEpcCoulomb; | |
313 | 319 | std::string messageVdWCorrectionTitle; |
314 | 320 | std::string messageVdWCorrection; |
315 | 321 | std::string messageElectronicDipoleMomentTitle; |
@@ -512,6 +518,7 @@ private: | ||
512 | 518 | double const* const* fockMatrix, |
513 | 519 | double const* const* gammaAB, |
514 | 520 | double coreRepulsionEnergy, |
521 | + double coreEpcCoulombEnergy, | |
515 | 522 | double vdWCorrectionEnergy) const; |
516 | 523 | void FreeElecEnergyMatrices(double*** fMatrix, |
517 | 524 | double*** hMatrix, |
@@ -326,6 +326,13 @@ double Mndo::GetDiatomCoreRepulsionEnergy(int indexAtomA, int indexAtomB) const{ | ||
326 | 326 | *tmp; |
327 | 327 | } |
328 | 328 | |
329 | +double Mndo::GetAtomCoreEpcCoulombEnergy(int indexAtom, int indexEpc) const{ | |
330 | + const Atom& atom = *this->molecule->GetAtom(indexAtom); | |
331 | + const Atom& epc = *this->molecule->GetAtom(indexEpc); | |
332 | + double distance = this->molecule->GetDistanceAtomEpc(indexAtom, indexEpc); | |
333 | + return atom.GetCoreCharge()*epc.GetCoreCharge()/distance; | |
334 | +} | |
335 | + | |
329 | 336 | // First derivative of diatomic core repulsion energy. |
330 | 337 | // This derivative is related to the coordinate of atomA. |
331 | 338 | double Mndo::GetDiatomCoreRepulsion1stDerivative(int indexAtomA, |
@@ -53,6 +53,7 @@ protected: | ||
53 | 53 | virtual void CalcNormalModes(double** normalModes, double* normalForceConstants, const MolDS_base::Molecule& molecule) const; |
54 | 54 | virtual void CalcForce(const std::vector<int>& elecStates); |
55 | 55 | virtual double GetDiatomCoreRepulsionEnergy(int indexAtomA, int indexAtomB) const; |
56 | + virtual double GetAtomCoreEpcCoulombEnergy (int indexAtom, int indexEpc ) const; | |
56 | 57 | virtual double GetDiatomCoreRepulsion1stDerivative(int indexAtomA, |
57 | 58 | int indexAtomB, |
58 | 59 | MolDS_base::CartesianType axisA) const; |