@@ -469,18 +469,22 @@ double Structure::calculateElectrostaticEnergy(
469469 A.resize (numAtoms + 1 , numAtoms + 1 );
470470 A.setZero ();
471471 VectorXd b (numAtoms + 1 );
472+ VectorXd hardnessJ (numAtoms);
472473
473474 double const sqrt2eta = sqrt (2.0 ) * grid.eta ;
474475
475476 if (isPeriodic)
476477 {
477478 // TODO: This part is not yet correct! Need to use real and reciprocal
478479 // cutoffs to avoid loop of order O(numAtoms^2).
480+ // UPDATE: should be fixed, but needs to be tested, therefore need periodic example with
481+ // electrostatic data
479482 for (size_t i = 0 ; i < numAtoms; ++i)
480483 {
481484 Atom const & ai = atoms.at (i);
482485 size_t const ei = ai.element ;
483486 A (i, i) = hardness (ei) + 1.0 / siggam (ei, ei);
487+ hardnessJ (i) = hardness (ei);
484488 b (i) = -ai.chi ;
485489 for (size_t j = i + 1 ; j < numAtoms; ++j)
486490 {
@@ -489,18 +493,20 @@ double Structure::calculateElectrostaticEnergy(
489493 {
490494 A (i, j) += gv.coeff * cos (gv.k * (ai.r - aj.r ));
491495 }
496+
497+ // still needs to be tested.
498+
499+ size_t const ej = aj.element ;
500+ double const rij = (ai.r - aj.r ).norm ();
501+ if (rij < rcutReal)
502+ {
503+ A (i, j) += (erfc (rij / sqrt2eta)
504+ - erfc (rij / siggam (ei, ej))) / rij;
505+ }
506+
492507 A (j, i) = A (i, j);
493508 }
494509 }
495- // TODO: Real part needs larger neighbor list (maybe set up 2nd
496- // neighbor list)!
497- // size_t const ej = aj.element;
498- // double const rij = (ai.r - aj.r).norm();
499- // if (rij < rcutReal)
500- // {
501- // A(i, j) += (erfc(rij / sqrt2eta)
502- // - erfc(rij / siggam(ei, ej))) / rij;
503- // }
504510 }
505511 else
506512 {
@@ -513,11 +519,13 @@ double Structure::calculateElectrostaticEnergy(
513519 // double f;
514520 // double df;
515521 // fs.fdf(rij, f, df)
522+ // UPDATE: Probably not needed here
516523 for (size_t i = 0 ; i < numAtoms; ++i)
517524 {
518525 Atom const & ai = atoms.at (i);
519526 size_t const ei = ai.element ;
520527 A (i, i) = hardness (ei) + 1.0 / siggam (ei, ei);
528+ hardnessJ (i) = hardness (ei);
521529 b (i) = -ai.chi ;
522530 for (size_t j = i + 1 ; j < numAtoms; ++j)
523531 {
@@ -544,9 +552,10 @@ double Structure::calculateElectrostaticEnergy(
544552 lambda = Q (numAtoms);
545553 double error = (A * Q - b).norm () / b.norm ();
546554
555+ // We need matrix E not A, which only differ by the hardness terms along the diagonal
547556 energyElec = 0.5 * Q.head (numAtoms).transpose ()
548- * A.topLeftCorner (numAtoms, numAtoms) * Q.head (numAtoms);
549-
557+ * ( A.topLeftCorner (numAtoms, numAtoms) - MatrixXd (hardnessJ. asDiagonal ()) ) * Q.head (numAtoms);
558+
550559 return error;
551560}
552561
0 commit comments