9
9
#include " gaussianset.h"
10
10
#include " molecule.h"
11
11
12
+ #include < iostream>
13
+
14
+ using std::vector;
15
+
12
16
namespace Avogadro ::Core {
13
17
14
18
GaussianSetTools::GaussianSetTools (Molecule* mol) : m_molecule(mol)
@@ -227,6 +231,12 @@ inline std::vector<double> GaussianSetTools::calculateValues(
227
231
case GaussianSet::F7:
228
232
pointF7 (i, deltas[atomIndices[i]], dr2[atomIndices[i]], values);
229
233
break ;
234
+ case GaussianSet::G:
235
+ pointG (i, deltas[atomIndices[i]], dr2[atomIndices[i]], values);
236
+ break ;
237
+ case GaussianSet::G9:
238
+ pointG9 (i, deltas[atomIndices[i]], dr2[atomIndices[i]], values);
239
+ break ;
230
240
default :
231
241
// Not handled - return a zero contribution
232
242
;
@@ -259,13 +269,13 @@ inline void GaussianSetTools::pointP(unsigned int moIndex, const Vector3& delta,
259
269
unsigned int baseIndex = m_basis->moIndices ()[moIndex];
260
270
Vector3 components (Vector3::Zero ());
261
271
262
- // Now iterate through the P type GTOs and sum their contributions
272
+ // Now iterate through the GTOs and sum their contributions
263
273
unsigned int cIndex = m_basis->cIndices ()[moIndex];
274
+ double tmpGTO = 0.0 ;
264
275
for (unsigned int i = m_basis->gtoIndices ()[moIndex];
265
276
i < m_basis->gtoIndices ()[moIndex + 1 ]; ++i) {
266
- double tmpGTO = exp (-m_basis->gtoA ()[i] * dr2);
277
+ tmpGTO = exp (-m_basis->gtoA ()[i] * dr2);
267
278
for (unsigned int j = 0 ; j < 3 ; ++j) {
268
- // m_values[baseIndex + i] = m_basis->gtoCN()[cIndex++] * tmpGTO;
269
279
components[j] += m_basis->gtoCN ()[cIndex++] * tmpGTO;
270
280
}
271
281
}
@@ -283,15 +293,16 @@ inline void GaussianSetTools::pointD(unsigned int moIndex, const Vector3& delta,
283
293
284
294
double components[6 ] = { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 };
285
295
286
- std:: vector<double >& gtoA = m_basis->gtoA ();
287
- std:: vector<double >& gtoCN = m_basis->gtoCN ();
296
+ const vector<double >& gtoA = m_basis->gtoA ();
297
+ const vector<double >& gtoCN = m_basis->gtoCN ();
288
298
289
- // Now iterate through the D type GTOs and sum their contributions
299
+ // Now iterate through the GTOs and sum their contributions
290
300
unsigned int cIndex = m_basis->cIndices ()[moIndex];
301
+ double tmpGTO = 0.0 ;
291
302
for (unsigned int i = m_basis->gtoIndices ()[moIndex];
292
303
i < m_basis->gtoIndices ()[moIndex + 1 ]; ++i) {
293
304
// Calculate the common factor
294
- double tmpGTO = exp (-gtoA[i] * dr2);
305
+ tmpGTO = exp (-gtoA[i] * dr2);
295
306
for (double & component : components)
296
307
component += gtoCN[cIndex++] * tmpGTO;
297
308
}
@@ -316,15 +327,16 @@ inline void GaussianSetTools::pointD5(unsigned int moIndex,
316
327
unsigned int baseIndex = m_basis->moIndices ()[moIndex];
317
328
double components[5 ] = { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 };
318
329
319
- std:: vector<double >& gtoA = m_basis->gtoA ();
320
- std:: vector<double >& gtoCN = m_basis->gtoCN ();
330
+ const vector<double >& gtoA = m_basis->gtoA ();
331
+ const vector<double >& gtoCN = m_basis->gtoCN ();
321
332
322
333
// Now iterate through the D type GTOs and sum their contributions
323
334
unsigned int cIndex = m_basis->cIndices ()[moIndex];
335
+ double tmpGTO = 0.0 ;
324
336
for (unsigned int i = m_basis->gtoIndices ()[moIndex];
325
337
i < m_basis->gtoIndices ()[moIndex + 1 ]; ++i) {
326
338
// Calculate the common factor
327
- double tmpGTO = exp (-gtoA[i] * dr2);
339
+ tmpGTO = exp (-gtoA[i] * dr2);
328
340
for (double & component : components)
329
341
component += gtoCN[cIndex++] * tmpGTO;
330
342
}
@@ -356,15 +368,16 @@ inline void GaussianSetTools::pointF(unsigned int moIndex, const Vector3& delta,
356
368
357
369
double components[10 ] = { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 };
358
370
359
- std:: vector<double >& gtoA = m_basis->gtoA ();
360
- std:: vector<double >& gtoCN = m_basis->gtoCN ();
371
+ const vector<double >& gtoA = m_basis->gtoA ();
372
+ const vector<double >& gtoCN = m_basis->gtoCN ();
361
373
362
- // Now iterate through the D type GTOs and sum their contributions
374
+ // Now iterate through the GTOs and sum their contributions
363
375
unsigned int cIndex = m_basis->cIndices ()[moIndex];
376
+ double tmpGTO = 0.0 ;
364
377
for (unsigned int i = m_basis->gtoIndices ()[moIndex];
365
378
i < m_basis->gtoIndices ()[moIndex + 1 ]; ++i) {
366
379
// Calculate the common factor
367
- double tmpGTO = exp (-gtoA[i] * dr2);
380
+ tmpGTO = exp (-gtoA[i] * dr2);
368
381
for (double & component : components)
369
382
component += gtoCN[cIndex++] * tmpGTO;
370
383
}
@@ -400,15 +413,16 @@ inline void GaussianSetTools::pointF7(unsigned int moIndex,
400
413
401
414
double components[7 ] = { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 };
402
415
403
- std:: vector<double >& gtoA = m_basis->gtoA ();
404
- std:: vector<double >& gtoCN = m_basis->gtoCN ();
416
+ const vector<double >& gtoA = m_basis->gtoA ();
417
+ const vector<double >& gtoCN = m_basis->gtoCN ();
405
418
406
- // Now iterate through the D type GTOs and sum their contributions
419
+ // Now iterate through the F type GTOs and sum their contributions
407
420
unsigned int cIndex = m_basis->cIndices ()[moIndex];
421
+ double tmpGTO = 0.0 ;
408
422
for (unsigned int i = m_basis->gtoIndices ()[moIndex];
409
423
i < m_basis->gtoIndices ()[moIndex + 1 ]; ++i) {
410
424
// Calculate the common factor
411
- double tmpGTO = exp (-gtoA[i] * dr2);
425
+ tmpGTO = exp (-gtoA[i] * dr2);
412
426
for (double & component : components)
413
427
component += gtoCN[cIndex++] * tmpGTO;
414
428
}
@@ -456,4 +470,102 @@ final normalization
456
470
values[baseIndex + i] += components[i] * componentsF[i];
457
471
}
458
472
473
+ inline void GaussianSetTools::pointG (unsigned int moIndex, const Vector3& delta,
474
+ double dr2, vector<double >& values) const
475
+ {
476
+ // G type orbitals have 15 components and each component has a different
477
+ // independent MO weighting. Many things can be cached to save time though.
478
+ unsigned int baseIndex = m_basis->moIndices ()[moIndex];
479
+
480
+ double components[15 ] = { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ,
481
+ 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 };
482
+
483
+ const vector<double >& gtoA = m_basis->gtoA ();
484
+ const vector<double >& gtoCN = m_basis->gtoCN ();
485
+
486
+ // Now iterate through the G type GTOs and sum their contributions
487
+ unsigned int cIndex = m_basis->cIndices ()[moIndex];
488
+ double tmpGTO = 0.0 ;
489
+ for (unsigned int i = m_basis->gtoIndices ()[moIndex];
490
+ i < m_basis->gtoIndices ()[moIndex + 1 ]; ++i) {
491
+ // Calculate the common factor
492
+ tmpGTO = exp (-gtoA[i] * dr2);
493
+ for (double & component : components)
494
+ component += gtoCN[cIndex++] * tmpGTO;
495
+ }
496
+
497
+ // e.g. XXXX YYYY ZZZZ XXXY XXXZ XYYY YYYZ ZZZX ZZZY XXYY XXZZ YYZZ XXYZ XYYZ
498
+ // XYZZ
499
+ const double xxxx = delta.x () * delta.x () * delta.x () * delta.x ();
500
+ const double yyyy = delta.y () * delta.y () * delta.y () * delta.y ();
501
+ const double zzzz = delta.z () * delta.z () * delta.z () * delta.z ();
502
+ const double xxxy = delta.x () * delta.x () * delta.x () * delta.y ();
503
+ const double xxxz = delta.x () * delta.x () * delta.x () * delta.z ();
504
+ const double yyyx = delta.y () * delta.y () * delta.y () * delta.x ();
505
+ const double yyyz = delta.y () * delta.y () * delta.y () * delta.z ();
506
+ const double zzzx = delta.z () * delta.z () * delta.z () * delta.x ();
507
+ const double zzzy = delta.z () * delta.z () * delta.z () * delta.y ();
508
+ const double xxyy = delta.x () * delta.x () * delta.y () * delta.y ();
509
+ const double xxzz = delta.x () * delta.x () * delta.z () * delta.z ();
510
+ const double yyzz = delta.y () * delta.y () * delta.z () * delta.z ();
511
+ const double xxyz = delta.x () * delta.x () * delta.y () * delta.z ();
512
+ const double yyxz = delta.y () * delta.y () * delta.x () * delta.z ();
513
+ const double zzxy = delta.z () * delta.z () * delta.x () * delta.y ();
514
+
515
+ // molden order
516
+ // https://www.theochem.ru.nl/molden/molden_format.html
517
+ // https://gau2grid.readthedocs.io/en/latest/order.html
518
+ // xxxx yyyy zzzz xxxy xxxz yyyx yyyz zzzx zzzy,
519
+ // xxyy xxzz yyzz xxyz yyxz zzxy
520
+ double componentsG[15 ] = { xxxx, yyyy, zzzz, xxxy, xxxz, yyyx, yyyz, zzzx,
521
+ zzzy, xxyy, xxzz, yyzz, xxyz, yyxz, zzxy };
522
+
523
+ for (int i = 0 ; i < 15 ; ++i)
524
+ values[baseIndex + i] += components[i] * componentsG[i];
525
+ }
526
+
527
+ inline void GaussianSetTools::pointG9 (unsigned int moIndex,
528
+ const Vector3& delta, double dr2,
529
+ vector<double >& values) const
530
+ {
531
+ // G type orbitals have 9 spherical components and each component
532
+ // has a different independent MO weighting.
533
+ // Many things can be cached to save time though.
534
+ unsigned int baseIndex = m_basis->moIndices ()[moIndex];
535
+
536
+ double components[9 ] = { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 };
537
+
538
+ const vector<double >& gtoA = m_basis->gtoA ();
539
+ const vector<double >& gtoCN = m_basis->gtoCN ();
540
+
541
+ // Now iterate through the GTOs and sum their contributions
542
+ unsigned int cIndex = m_basis->cIndices ()[moIndex];
543
+ double tmpGTO = 0.0 ;
544
+ for (unsigned int i = m_basis->gtoIndices ()[moIndex];
545
+ i < m_basis->gtoIndices ()[moIndex + 1 ]; ++i) {
546
+ // Calculate the common factor
547
+ tmpGTO = exp (-gtoA[i] * dr2);
548
+ for (double & component : components)
549
+ component += gtoCN[cIndex++] * tmpGTO;
550
+ }
551
+
552
+ double x2 (delta.x () * delta.x ()), y2 (delta.y () * delta.y ()),
553
+ z2 (delta.z () * delta.z ());
554
+
555
+ double componentsG[9 ] = {
556
+ 3.0 * dr2 * dr2 - 30.0 * dr2 * z2 + 35.0 * z2 * z2 * (1.0 / 8.0 ),
557
+ delta.x () * delta.z () * (7.0 * z2 - 3.0 * dr2) * (sqrt (5.0 ) / 8.0 ),
558
+ delta.y () * delta.z () * (7.0 * z2 - 3.0 * dr2) * (sqrt (5.0 ) / 8.0 ),
559
+ (x2 - y2) * (7.0 * z2 - dr2) * (sqrt (5.0 ) / 4.0 ),
560
+ delta.x () * delta.y () * (7.0 * z2 - dr2) * (sqrt (5.0 ) / 2.0 ),
561
+ delta.x () * delta.z () * (x2 - 3.0 * y2) * (sqrt (7.0 ) / 4.0 ),
562
+ delta.y () * delta.z () * (3.0 * x2 - y2) * (sqrt (7.0 ) / 4.0 ),
563
+ (x2 * x2 - 6.0 * x2 * y2 + y2 * y2) * (sqrt (35.0 ) / 8.0 ),
564
+ delta.x () * delta.y () * (x2 - y2) * (sqrt (35.0 ) / 2.0 )
565
+ };
566
+
567
+ for (int i = 0 ; i < 9 ; ++i)
568
+ values[baseIndex + i] += components[i] * componentsG[i];
569
+ }
570
+
459
571
} // namespace Avogadro::Core
0 commit comments