@@ -301,9 +301,9 @@ inline double TanhSphericalDiffuse::functionSummation(int L, double r1, double r
301301 return gr12;
302302}
303303
304- /* ! Calcualtes the Green's function given a pair of points */
304+ /* ! Calculates the Green's function given a pair of points */
305305template <>
306- inline Numerical GreensFunction<Numerical, TanhDiffuse>::function(const Eigen::Vector3d & source,
306+ inline double GreensFunction<Numerical, TanhDiffuse>::function(const Eigen::Vector3d & source,
307307 const Eigen::Vector3d & probe) const
308308{
309309 Numerical sp[3 ], pp[3 ];
@@ -372,6 +372,7 @@ inline Eigen::Vector3d TanhSphericalDiffuse::coefficientGradient(const Eigen::Ve
372372 double r2 = p2.norm ();
373373 double r2_2 = std::pow (r2, 2 );
374374 double r2_3 = std::pow (r2, 3 );
375+ double prod = p1.dot (p2);
375376 double r12 = (p1 - p2).norm ();
376377 double cos_gamma = p1.dot (p2) / (r1 * r2);
377378 double cos_gamma_2 = std::pow (cos_gamma, 2 );
@@ -416,11 +417,11 @@ inline Eigen::Vector3d TanhSphericalDiffuse::coefficientGradient(const Eigen::Ve
416417 Eigen::Vector3d tmp_grad = Eigen::Vector3d::Zero ();
417418 if (r1 < r2) {
418419 double expFact = std::exp (zeta1 -zeta2) * (2 *maxLC_ + 1 );
419- tmp_grad (0 ) = -expFact*x2/((d_zeta2-d_omega2)*r2_3*eps_r2) * (a + b - (x1*r2*r2/x2-r12 )*pl_first_x/
420+ tmp_grad (0 ) = -expFact*x2/((d_zeta2-d_omega2)*r2_3*eps_r2) * (a + b - (x1*r2*r2/x2-prod )*pl_first_x/
420421 (r1*r2*r2));
421- tmp_grad (1 ) = -expFact*y2/((d_zeta2-d_omega2)*r2_3*eps_r2) * (a + b - (y1*r2*r2/y2-r12 )*pl_first_x/
422+ tmp_grad (1 ) = -expFact*y2/((d_zeta2-d_omega2)*r2_3*eps_r2) * (a + b - (y1*r2*r2/y2-prod )*pl_first_x/
422423 (r1*r2*r2));
423- tmp_grad (2 ) = -expFact*z2/((d_zeta2-d_omega2)*r2_3*eps_r2) * (a + b - (z1*r2*r2/z2-r12 )*pl_first_x/
424+ tmp_grad (2 ) = -expFact*z2/((d_zeta2-d_omega2)*r2_3*eps_r2) * (a + b - (z1*r2*r2/z2-prod )*pl_first_x/
424425 (r1*r2*r2));
425426
426427 double powl = std::pow (r1/r2, maxLC_);
@@ -432,12 +433,12 @@ inline Eigen::Vector3d TanhSphericalDiffuse::coefficientGradient(const Eigen::Ve
432433 p2)))/(r1*r2))/(r2_3*tmp_grad (2 ));
433434 } else {
434435 double expFact = exp (omega1 - omega2) * (2 *maxLC_ + 1 );
435- tmp_grad (0 ) = -expFact*x2/((d_zeta2-d_omega2)*r2_3*eps_r2) * (a + c - (x1*r2*r2/x2-r12)*pl_first_x/
436- (r1*r2*r2));
437- tmp_grad (1 ) = -expFact*y2/((d_zeta2-d_omega2)*r2_3*eps_r2) * (a + c - (y1*r2*r2/y2-r12)*pl_first_x/
438- (r1*r2*r2));
439- tmp_grad (2 ) = -expFact*z2/((d_zeta2-d_omega2)*r2_3*eps_r2) * (a + c - (z1*r2*r2/z2-r12)*pl_first_x/
440- (r1*r2*r2));
436+ tmp_grad (0 ) = -expFact*x2/((d_zeta2-d_omega2)*r2_3*eps_r2) *
437+ (a + c - (x1*r2*r2/x2 - prod) * pl_first_x / (r1*r2*r2));
438+ tmp_grad (1 ) = -expFact*y2/((d_zeta2-d_omega2)*r2_3*eps_r2) *
439+ (a + c - (y1*r2*r2/y2 - prod) * pl_first_x / (r1*r2*r2));
440+ tmp_grad (2 ) = -expFact*z2/((d_zeta2-d_omega2)*r2_3*eps_r2)
441+ * (a + c - (z1*r2*r2/z2 - prod) * pl_first_x / (r1*r2*r2));
441442
442443 double powl = std::pow (r2/r1, maxLC_);
443444 coeff_grad (0 ) = powl*(pl_x*p2 (0 )*maxLC_+pl_first_x*(p1 (0 )*r2_2 -p2 (0 )*(p1.dot (p2)))/
@@ -453,112 +454,48 @@ inline Eigen::Vector3d TanhSphericalDiffuse::coefficientGradient(const Eigen::Ve
453454
454455template <>
455456inline Eigen::Vector3d TanhSphericalDiffuse::functionSummationGradient (int L, const Eigen::Vector3d & p1,
456- const Eigen::Vector3d & p2, double Cr12 ) const
457+ const Eigen::Vector3d & p2, const Eigen::Vector3d & Cr12_grad ) const
457458{
458459 Eigen::Vector3d gr12_grad = Eigen::Vector3d::Zero ();
459- return gr12_grad;
460- }
461-
462- template <>
463- inline Numerical GreensFunction<Numerical, TanhDiffuse>::derivativeProbe(const Eigen::Vector3d & normal_p2,
464- const Eigen::Vector3d & p1, const Eigen::Vector3d & p2) const
465- {
466- double eps_r2 = 0.0 , epsPrime_r2 = 0.0 ;
467- this ->profile_ (eps_r2, epsPrime_r2, p2.norm ());
468- Eigen::Vector3d grad = Eigen::Vector3d::Zero ();
469-
470- // To be implemented
471- return (eps_r2 * grad.dot (normal_p2));
472- }
473-
474- /*
475- Eigen::Vector3d SphericalInterface::converged_deri_gf(const Eigen::VectorXd & p1,
476- const Eigen::VectorXd & p2, double *plx,
477- double *dplx) const
478- {
479- Eigen::Vector3d greenGradient(0.0, 0.0, 0.0);
480- Eigen::Vector3d Cr12Gradient(0.0, 0.0, 0.0);
481- double r1 = p1.norm();
482- double r2 = p2.norm();
483- double eps2, deps2;
484- profile(&eps2, &deps2, r2);
485-
486- double pl = plx[maxLEpsilon_];
487- double dpl = dplx[maxLEpsilon_];
488-
489- Cr12Gradient.Zero();
490- greenGradient = greenfunc_der(p1, p2, Cr12Gradient, radialC1_, radialC2_,
491- pl, dpl, maxLEpsilon_, 0);
492- if (r1 < r2) {
493- double powl = std::pow(r1/r2, maxLEpsilon_);
494- Cr12Gradient(0) = powl*(pl*p2(0)*(-maxLEpsilon_-1)+dpl*(p1(0)*r2*r2-p2(0)*(p1.dot(
495- p2)))/(r1*r2))/(r2*r2*r2*greenGradient(0));
496- Cr12Gradient(1) = powl*(pl*p2(1)*(-maxLEpsilon_-1)+dpl*(p1(1)*r2*r2-p2(1)*(p1.dot(
497- p2)))/(r1*r2))/(r2*r2*r2*greenGradient(1));
498- Cr12Gradient(2) = powl*(pl*p2(2)*(-maxLEpsilon_-1)+dpl*(p1(2)*r2*r2-p2(2)*(p1.dot(
499- p2)))/(r1*r2))/(r2*r2*r2*greenGradient(2));
500- } else {
501- double powl = std::pow(r2/r1, maxLEpsilon_);
502- Cr12Gradient(0) = powl*(pl*p2(0)*maxLEpsilon_+dpl*(p1(0)*r2*r2-p2(0)*(p1.dot(p2)))/
503- (r1*r2))/(r1*r2*r2*greenGradient(0));
504- Cr12Gradient(1) = powl*(pl*p2(1)*maxLEpsilon_+dpl*(p1(1)*r2*r2-p2(1)*(p1.dot(p2)))/
505- (r1*r2))/(r1*r2*r2*greenGradient(1));
506- Cr12Gradient(2) = powl*(pl*p2(2)*maxLEpsilon_+dpl*(p1(2)*r2*r2-p2(2)*(p1.dot(p2)))/
507- (r1*r2))/(r1*r2*r2*greenGradient(2));
508- }
509460
510- greenGradient.Zero();
511-
512- for (int l = 0; l < maxLGreen_; ++l) {
513- Eigen::Vector3d gl = greenfunc_der(p1, p2, Cr12Gradient, radialG1_[l],
514- radialG2_[l], plx[l], dplx[l], l, 1);
515- greenGradient += gl;
516- }
517-
518- double r12 = (p1-p2).norm();
519- Eigen::Vector3d gr_d;
520- gr_d.array() = (p1.array() - p2.array()) /
521- (Cr12Gradient.array() * r12 * r12 * r12) + greenGradient.array();
522- gr_d *= -1;
523- return gr_d;
524- }
525-
526- // greenGradient = greenfunc_der(p1, p2, Cr12Gradient, radialC1_, radialC2_, pl, dpl, maxLEpsilon_, 0);
527-
528- Eigen::Vector3d SphericalInterface::greenfunc_der(const Eigen::Vector3d & p1,
529- const Eigen::Vector3d & p2, const Eigen::Vector3d & Cr12,
530- const FuncGrid & f1, const FuncGrid & f2, double plx,
531- double dplx, int l, int flagCr12) const
532- {
533- double eps2, deps2;
461+ double r1 = p1.norm ();
462+ double r2 = p2.norm ();
463+ double r2_2 = std::pow (r2, 2 );
464+ double r2_3 = std::pow (r2, 3 );
534465 double prod = p1.dot (p2);
535- double r1 = p1.norm();
536- double r2 = p2.norm();
537- double r2_3 = r2 * r2 * r2;
538- profile(&eps2, &deps2, r2);
539-
540- //calculate Legendre function of L and x--cos_angle
466+ double r12 = (p1 - p2).norm ();
467+ double cos_gamma = p1.dot (p2) / (r1 * r2);
468+ double cos_gamma_2 = std::pow (cos_gamma, 2 );
541469
542- int idx1 = int((r1-rBegin_) / hStep_) - 1;
543- int idx2 = int((r2-rBegin_) / hStep_) - 1;
470+ double pl_x = boost::math::legendre_p (maxLC_, cos_gamma);
471+ double pl_first_x = -boost::math::legendre_p (maxLC_, 1 , cos_gamma)
472+ / (std::sqrt (1.0 - std::pow (cos_gamma, 2 )));
544473
545- double delta1 = r1 - grid_(idx1) ;
546- double delta2 = r2 - grid_(idx2 );
474+ double eps_r2 = 0.0 , epsPrime_r2 = 0.0 ;
475+ this -> profile_ (eps_r2, epsPrime_r2, r2 );
547476
477+ /* Value of zetaC_ at point with index 1 */
478+ double zeta1 = linearInterpolation (r1, zetaC_[0 ], zetaC_[1 ]);
479+ /* Value of zetaC_ at point with index 2 */
480+ double zeta2 = linearInterpolation (r2, zetaC_[0 ], zetaC_[1 ]);
481+ /* Value of omegaC_ at point with index 1 */
482+ double omega1 = linearInterpolation (r1, omegaC_[0 ], omegaC_[1 ]);
483+ /* Value of omegaC_ at point with index 2 */
484+ double omega2 = linearInterpolation (r2, omegaC_[0 ], omegaC_[1 ]);
548485
549- double u11 = f1(0, idx1) + (f1(0, idx1 + 1) - f1(0, idx1)) * delta1 / hStep_;
550- double u12 = f1(0, idx2) + (f1(0, idx2 + 1) - f1(0, idx2)) * delta2 / hStep_ ;
551- double u21 = f2(0, idx1) + (f2(0, idx1 + 1) - f2(0, idx1)) * delta1 / hStep_;
552- double u22 = f2(0, idx2) + (f2(0, idx2 + 1) - f2(0, idx2)) * delta2 / hStep_ ;
486+ /* Value of derivative of zetaC_ at point with index 2 */
487+ double d_zeta2 = linearInterpolation (r2, zetaC_[ 0 ], zetaC_[ 2 ]) ;
488+ /* Value of derivative of omegaC_ at point with index 2 */
489+ double d_omega2 = linearInterpolation (r2, omegaC_[ 0 ], omegaC_[ 2 ]) ;
553490
554- double d11 = f1(1, idx1) + (f1(1, idx1 + 1) - f1(1, idx1)) * delta1 / hStep_;
555- double d12 = f1(1, idx2) + (f1(1, idx2 + 1) - f1(1, idx2)) * delta2 / hStep_ ;
556- double d21 = f2(1, idx1) + (f2(1, idx1 + 1) - f2(1, idx1)) * delta1 / hStep_;
557- double d22 = f2(1, idx2) + (f2(1, idx2 + 1) - f2(1, idx2)) * delta2 / hStep_ ;
491+ /* ! Value of second derivative of zetaC_ at point with index 2 */
492+ double d2_zeta2 = maxLC_ * (maxLC_ + 1 ) / r2_2 - std::pow (d_zeta2, 2 ) - ( 2.0 / r2 + epsPrime_r2 / eps_r2) * d_zeta2 ;
493+ /* ! Value of second derivative of omegaC_ at point with index 2 */
494+ double d2_omega2 = maxLC_ * (maxLC_ + 1 ) / r2_2 - std::pow (d_omega2, 2 ) - ( 2.0 / r2 + epsPrime_r2 / eps_r2) * d_omega2 ;
558495
559- double d2u12 = l * (l + 1) / (r2*r2) - d12 * d12 - ( 2.0 / r2 + deps2 / eps2) * d12 ;
560- double d2u22 = l * (l + 1) / (r2*r2) - d22 * d22 - (2.0 / r2 + deps2 / eps2) * d22 ;
561- Eigen::Vector3d g12_deri ;
496+ double a = (epsPrime_r2 * r2 + 2.0 * eps_r2) * pl_x / (eps_r2 * r2) ;
497+ double b = (d_zeta2 * (d_zeta2 - d_omega2) + d2_zeta2 - d2_omega2) * pl_x / (d_zeta2 - d_omega2) ;
498+ double c = (d_omega2 * (d_zeta2 - d_omega2) + d2_zeta2 - d2_omega2) * pl_x / (d_zeta2 - d_omega2) ;
562499
563500 double x1 = p1 (0 );
564501 double y1 = p1 (1 );
@@ -567,48 +504,51 @@ Eigen::Vector3d SphericalInterface::greenfunc_der(const Eigen::Vector3d & p1,
567504 double y2 = p2 (1 );
568505 double z2 = p2 (2 );
569506
570- double a = (deps2*r2+2.0*eps2)*plx/(eps2*r2);
571- double b = (d12*(d12-d22)+d2u12-d2u22)*plx/(d12-d22);
572- double c = (d22*(d12-d22)+d2u12-d2u22)*plx/(d12-d22);
573- if (r1<r2) {
574- double expFact = exp(u11-u12)*(2*l+1);
575- g12_deri(0) = -expFact*x2/((d12-d22)*r2_3*eps2) * (a + b - (x1*r2*r2/x2-prod)*dplx/
576- (r1*r2*r2));
577- g12_deri(1) = -expFact*y2/((d12-d22)*r2_3*eps2) * (a + b - (y1*r2*r2/y2-prod)*dplx/
578- (r1*r2*r2));
579- g12_deri(2) = -expFact*z2/((d12-d22)*r2_3*eps2) * (a + b - (z1*r2*r2/z2-prod)*dplx/
580- (r1*r2*r2));
581- if (flagCr12 == 1) {
582- g12_deri(0) -= (std::pow(r1/r2,
583- l)*(plx*x2*(-l-1)+dplx*(x1*r2*r2-x2*prod)/(r1*r2))/(r2_3*Cr12(0)));
584- g12_deri(1) -= (std::pow(r1/r2,
585- l)*(plx*y2*(-l-1)+dplx*(y1*r2*r2-y2*prod)/(r1*r2))/(r2_3*Cr12(1)));
586- g12_deri(2) -= (std::pow(r1/r2,
587- l)*(plx*z2*(-l-1)+dplx*(z1*r2*r2-z2*prod)/(r1*r2))/(r2_3*Cr12(2)));
588- }
589- } else {
590- double expFact = exp(u21-u22)*(2*l+1);
591- g12_deri(0) = -expFact*x2/((d12-d22)*r2_3*eps2) * (a + c - (x1*r2*r2/x2-prod)*dplx/
592- (r1*r2*r2));
593- g12_deri(1) = -expFact*y2/((d12-d22)*r2_3*eps2) * (a + c - (y1*r2*r2/y2-prod)*dplx/
594- (r1*r2*r2));
595- g12_deri(2) = -expFact*z2/((d12-d22)*r2_3*eps2) * (a + c - (z1*r2*r2/z2-prod)*dplx/
596- (r1*r2*r2));
597- if (flagCr12 == 1) {
598- g12_deri(0) -= (std::pow(r2/r1,
599- l)*(plx*x2*l+dplx*(x1*r2*r2-x2*prod)/(r1*r2))/(r1*r2*r2*Cr12(0)));
600- g12_deri(1) -= (std::pow(r2/r1,
601- l)*(plx*y2*l+dplx*(y1*r2*r2-y2*prod)/(r1*r2))/(r1*r2*r2*Cr12(1)));
602- g12_deri(2) -= (std::pow(r2/r1,
603- l)*(plx*z2*l+dplx*(z1*r2*r2-z2*prod)/(r1*r2))/(r1*r2*r2*Cr12(2)));
604- }
507+ if (r1 < r2) {
508+ double expFact = exp (zeta1-zeta2)*(2 *L+1 );
509+ gr12_grad (0 ) = -expFact*x2/((d_zeta2-d_omega2)*r2_3*eps_r2) * (a + b - (x1*r2*r2/x2-prod)*pl_first_x/(r1*r2*r2));
510+ gr12_grad (1 ) = -expFact*y2/((d_zeta2-d_omega2)*r2_3*eps_r2) * (a + b - (y1*r2*r2/y2-prod)*pl_first_x/(r1*r2*r2));
511+ gr12_grad (2 ) = -expFact*z2/((d_zeta2-d_omega2)*r2_3*eps_r2) * (a + b - (z1*r2*r2/z2-prod)*pl_first_x/(r1*r2*r2));
512+ gr12_grad (0 ) -= (pow (r1/r2,L)*(pl_x*x2*(-L-1 )+pl_first_x*(x1*r2*r2-x2*prod)/(r1*r2))/(r2_3*Cr12_grad (0 )));
513+ gr12_grad (1 ) -= (pow (r1/r2,L)*(pl_x*y2*(-L-1 )+pl_first_x*(y1*r2*r2-y2*prod)/(r1*r2))/(r2_3*Cr12_grad (1 )));
514+ gr12_grad (2 ) -= (pow (r1/r2,L)*(pl_x*z2*(-L-1 )+pl_first_x*(z1*r2*r2-z2*prod)/(r1*r2))/(r2_3*Cr12_grad (2 )));
515+ } else {
516+ double expFact = exp (omega1-omega2)*(2 *L+1 );
517+ gr12_grad (0 ) = -expFact*x2/((d_zeta2-d_omega2)*r2_3*eps_r2) * (a + c - (x1*r2*r2/x2-prod)*pl_first_x/(r1*r2*r2));
518+ gr12_grad (1 ) = -expFact*y2/((d_zeta2-d_omega2)*r2_3*eps_r2) * (a + c - (y1*r2*r2/y2-prod)*pl_first_x/(r1*r2*r2));
519+ gr12_grad (2 ) = -expFact*z2/((d_zeta2-d_omega2)*r2_3*eps_r2) * (a + c - (z1*r2*r2/z2-prod)*pl_first_x/(r1*r2*r2));
520+ gr12_grad (0 ) -= (pow (r2/r1,L)*(pl_x*x2*L+pl_first_x*(x1*r2*r2-x2*prod)/(r1*r2))/(r1*r2*r2*Cr12_grad (0 )));
521+ gr12_grad (1 ) -= (pow (r2/r1,L)*(pl_x*y2*L+pl_first_x*(y1*r2*r2-y2*prod)/(r1*r2))/(r1*r2*r2*Cr12_grad (1 )));
522+ gr12_grad (2 ) -= (pow (r2/r1,L)*(pl_x*z2*L+pl_first_x*(z1*r2*r2-z2*prod)/(r1*r2))/(r1*r2*r2*Cr12_grad (2 )));
523+ }
524+
525+ return gr12_grad;
526+ }
527+
528+ template <>
529+ inline double SphericalDiffuse<TanhDiffuse>::derivativeProbe(const Eigen::Vector3d & normal_p2,
530+ const Eigen::Vector3d & p1, const Eigen::Vector3d & p2) const
531+ {
532+ double eps_r2 = 0.0 , epsPrime_r2 = 0.0 ;
533+ this ->profile_ (eps_r2, epsPrime_r2, p2.norm ());
534+
535+ Eigen::Vector3d Cr12_grad = this ->coefficientGradient (p1, p2);
536+ Eigen::Vector3d grad = Eigen::Vector3d::Zero ();
537+ for (int L = 0 ; L < maxLGreen_; ++L) {
538+ grad += this ->functionSummationGradient (L, p1, p2, Cr12_grad);
605539 }
606- return g12_deri;
540+
541+ double r12 = (p1 - p2).norm ();
542+ Eigen::Vector3d gr_d = Eigen::Vector3d::Zero ();
543+ gr_d.array () = (p1.array () - p2.array ()) /
544+ (Cr12_grad.array () * std::pow (r12, 3 )) + grad.array ();
545+ gr_d *= -1 ;
546+
547+ return (eps_r2 * grad.dot (normal_p2));
607548}
608- */
609549
610550template <>
611- inline Numerical GreensFunction<Numerical, TanhDiffuse>::derivativeSource(const Eigen::Vector3d & normal_p1,
551+ inline double GreensFunction<Numerical, TanhDiffuse>::derivativeSource(const Eigen::Vector3d & normal_p1,
612552 const Eigen::Vector3d & p1, const Eigen::Vector3d & p2) const
613553{
614554 // To be implemented
0 commit comments