|  | @@ -499,6 +499,108 @@ namespace nmie {
 | 
	
		
			
				|  |  |        Psi[n] = Psi[n - 1]*(n/x - D1[n - 1]);
 | 
	
		
			
				|  |  |        Zeta[n] = Zeta[n - 1]*(n/x - D3[n - 1]);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  //**********************************************************************************//
 | 
	
		
			
				|  |  | +  // Function CONFRA ported from MIEV0.f (Wiscombe,1979)
 | 
	
		
			
				|  |  | +  // Ref. to NCAR Technical Notes, Wiscombe, 1979
 | 
	
		
			
				|  |  | +  /*
 | 
	
		
			
				|  |  | +c         Compute Bessel function ratio A-sub-N from its
 | 
	
		
			
				|  |  | +c         continued fraction using Lentz method
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +c         ZINV = Reciprocal of argument of A
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +c    I N T E R N A L    V A R I A B L E S
 | 
	
		
			
				|  |  | +c    ------------------------------------
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +c    CAK      Term in continued fraction expansion of A (Eq. R25)
 | 
	
		
			
				|  |  | +c     a_k
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +c    CAPT     Factor used in Lentz iteration for A (Eq. R27)
 | 
	
		
			
				|  |  | +c     T_k
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +c    CNUMER   Numerator   in capT  ( Eq. R28A )
 | 
	
		
			
				|  |  | +c     N_k
 | 
	
		
			
				|  |  | +c    CDENOM   Denominator in capT  ( Eq. R28B )
 | 
	
		
			
				|  |  | +c     D_k
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +c    CDTD     Product of two successive denominators of capT factors
 | 
	
		
			
				|  |  | +c                 ( Eq. R34C )
 | 
	
		
			
				|  |  | +c     xi_1
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +c    CNTN     Product of two successive numerators of capT factors
 | 
	
		
			
				|  |  | +c                 ( Eq. R34B )
 | 
	
		
			
				|  |  | +c     xi_2
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +c    EPS1     Ill-conditioning criterion
 | 
	
		
			
				|  |  | +c    EPS2     Convergence criterion
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +c    KK       Subscript k of cAk  ( Eq. R25B )
 | 
	
		
			
				|  |  | +c     k
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +c    KOUNT    Iteration counter ( used to prevent infinite looping )
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +c    MAXIT    Max. allowed no. of iterations
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +c    MM       + 1  and - 1, alternately
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +  std::complex<double> MultiLayerMie::calcD1confra(const std::complex<double> z) {
 | 
	
		
			
				|  |  | +  // NTMR -> nmax_ -1  \\TODO nmax_ ?
 | 
	
		
			
				|  |  | +    int N = nmax_ - 1;
 | 
	
		
			
				|  |  | +    int KK, KOUNT, MAXIT = 10000, MM;
 | 
	
		
			
				|  |  | +    double EPS1=1.0e-2, EPS2=1.0e-8;
 | 
	
		
			
				|  |  | +    std::complex<double> CAK, CAPT, CDENOM, CDTD, CNTN, CNUMER;
 | 
	
		
			
				|  |  | +    std::complex<double> one = std::complex<double>(1.0,0.0);
 | 
	
		
			
				|  |  | +    std::complex<double> ZINV = one/z;
 | 
	
		
			
				|  |  | +// c                                 ** Eq. R25a
 | 
	
		
			
				|  |  | +    std::complex<double> CONFRA = static_cast<std::complex<double> >(N+1)*ZINV;  
 | 
	
		
			
				|  |  | +    MM = -1;
 | 
	
		
			
				|  |  | +    KK = 2*N +3;
 | 
	
		
			
				|  |  | +// c                                 ** Eq. R25b, k=2
 | 
	
		
			
				|  |  | +    CAK    = static_cast<std::complex<double> >(MM*KK) * ZINV;
 | 
	
		
			
				|  |  | +    CDENOM = CAK;
 | 
	
		
			
				|  |  | +    CNUMER = CDENOM + one / CONFRA;
 | 
	
		
			
				|  |  | +    KOUNT  = 1;
 | 
	
		
			
				|  |  | +    //10 CONTINUE
 | 
	
		
			
				|  |  | +    do {      ++KOUNT;
 | 
	
		
			
				|  |  | +      if (KOUNT > MAXIT) {	printf("re(%g):im(%g)\t\n", CONFRA.real(), CONFRA.imag()); break;
 | 
	
		
			
				|  |  | +	throw std::invalid_argument("ConFra--Iteration failed to converge!\n"); }
 | 
	
		
			
				|  |  | +      MM *= -1;      KK += 2;
 | 
	
		
			
				|  |  | +      CAK = static_cast<std::complex<double> >(MM*KK) * ZINV; //    ** Eq. R25b
 | 
	
		
			
				|  |  | +     //  //c ** Eq. R32    Ill-conditioned case -- stride two terms instead of one
 | 
	
		
			
				|  |  | +     //  if (std::abs( CNUMER / CAK ) >= EPS1 ||  std::abs( CDENOM / CAK ) >= EPS1) {
 | 
	
		
			
				|  |  | +     // 	//c                       ** Eq. R34
 | 
	
		
			
				|  |  | +     // 	CNTN   = CAK * CNUMER + 1.0;
 | 
	
		
			
				|  |  | +     // 	CDTD   = CAK * CDENOM + 1.0;
 | 
	
		
			
				|  |  | +     // 	CONFRA = ( CNTN / CDTD ) * CONFRA; // ** Eq. R33
 | 
	
		
			
				|  |  | +     // 	MM  *= -1;	KK  += 2;
 | 
	
		
			
				|  |  | +     // 	CAK = static_cast<std::complex<double> >(MM*KK) * ZINV; // ** Eq. R25b
 | 
	
		
			
				|  |  | +     // 	//c                        ** Eq. R35
 | 
	
		
			
				|  |  | +     // 	CNUMER = CAK + CNUMER / CNTN;
 | 
	
		
			
				|  |  | +     // 	CDENOM = CAK + CDENOM / CDTD;
 | 
	
		
			
				|  |  | +     // 	++KOUNT;
 | 
	
		
			
				|  |  | +     // 	//GO TO  10
 | 
	
		
			
				|  |  | +     // 	continue;
 | 
	
		
			
				|  |  | +     // } else { //c                           *** Well-conditioned case
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +	CAPT   = CNUMER / CDENOM; // ** Eq. R27
 | 
	
		
			
				|  |  | +       printf("re(%g):im(%g)**\t", CAPT.real(), CAPT.imag());
 | 
	
		
			
				|  |  | +       CONFRA = CAPT * CONFRA; // ** Eq. R26
 | 
	
		
			
				|  |  | +       //       printf("re(%g):im(%g)\t", CONFRA.real(), CONFRA.imag());
 | 
	
		
			
				|  |  | +//c                                  ** Check for convergence; Eq. R31
 | 
	
		
			
				|  |  | +       if ( std::abs(CAPT.real() - 1.0) >= EPS2 ||  std::abs(CAPT.imag()) >= EPS2 ) {
 | 
	
		
			
				|  |  | +//c                                        ** Eq. R30
 | 
	
		
			
				|  |  | +	 CNUMER = CAK + one/CNUMER;
 | 
	
		
			
				|  |  | +	 CDENOM = CAK + one/CDENOM;
 | 
	
		
			
				|  |  | +	 continue;
 | 
	
		
			
				|  |  | +	 //GO TO  10
 | 
	
		
			
				|  |  | +       }  // end of if < eps2
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      break;
 | 
	
		
			
				|  |  | +    } while(1);    
 | 
	
		
			
				|  |  | +    printf(" return confra\n");
 | 
	
		
			
				|  |  | +    return CONFRA;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    //**********************************************************************************//
 | 
	
		
			
				|  |  |    // This function calculates the logarithmic derivatives of the Riccati-Bessel       //
 | 
	
	
		
			
				|  | @@ -507,7 +609,7 @@ namespace nmie {
 | 
	
		
			
				|  |  |    //                                                                                  //
 | 
	
		
			
				|  |  |    // Input parameters:                                                                //
 | 
	
		
			
				|  |  |    //   z: Complex argument to evaluate D1 and D3                                      //
 | 
	
		
			
				|  |  | -  //   nmax_: Maximum number of terms to calculate D1 and D3                           //
 | 
	
		
			
				|  |  | +  //   nmax_: Maximum number of terms to calculate D1 and D3                          //
 | 
	
		
			
				|  |  |    //                                                                                  //
 | 
	
		
			
				|  |  |    // Output parameters:                                                               //
 | 
	
		
			
				|  |  |    //   D1, D3: Logarithmic derivatives of the Riccati-Bessel functions                //
 | 
	
	
		
			
				|  | @@ -516,8 +618,12 @@ namespace nmie {
 | 
	
		
			
				|  |  |  			       std::vector<std::complex<double> >& D1,
 | 
	
		
			
				|  |  |  			       std::vector<std::complex<double> >& D3) {
 | 
	
		
			
				|  |  |      // Downward recurrence for D1 - equations (16a) and (16b)
 | 
	
		
			
				|  |  | -    D1[nmax_] = std::complex<double>(0.0, 0.0);
 | 
	
		
			
				|  |  | +    //D1[nmax_] = std::complex<double>(0.0, 0.0);
 | 
	
		
			
				|  |  | +    D1[nmax_] = calcD1confra(z);
 | 
	
		
			
				|  |  |      const std::complex<double> zinv = std::complex<double>(1.0, 0.0)/z;
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    printf(" D:");prn((D1[nmax_]).real()); printf("\t diff:");
 | 
	
		
			
				|  |  | +    prn((D1[nmax_] + double(nmax_)*zinv).real());
 | 
	
		
			
				|  |  |      for (int n = nmax_; n > 0; n--) {
 | 
	
		
			
				|  |  |        D1[n - 1] = double(n)*zinv - 1.0/(D1[n] + double(n)*zinv);
 | 
	
		
			
				|  |  |        printf(" D:");prn((D1[n-1]).real()); printf("\t diff:");
 |