/home66/gary/public_html/cloudy/c08_branch/source/hydro_bauman.cpp

Go to the documentation of this file.
00001 /* This file is part of Cloudy and is copyright (C)1978-2008 by Gary J. Ferland and
00002  * others.  For conditions of distribution and use see copyright notice in license.txt */
00003 /************************************************************************************************/
00004 /*H_photo_cs_lin returns hydrogenic photoionization cross section in cm-2                       */
00005 /*H_Einstein_A_lin calculates Einstein A for any nlz                                            */
00006 /*hv calculates photon energy in ergs for n -> n' transitions for H and H-like ions             */
00007 /************************************************************************************************/
00008 /***************************  LOG version of h_bauman.c  ****************************************/
00009 /* In this version, quantities that would normally cause a 64-bit floating point processor      */
00010 /* to either underflow or overflow are evaluated using logs instead of floating point math.     */
00011 /* This allows us to use an upper principal quantum number `n' greater than  which the          */
00012 /* other version begins to fail. The trade-off is, of course, lower accuracy                    */
00013 /* ( or is it precision ). We use LOG_10 for convenience.                                       */
00014 /************************************************************************************************/
00015 #include "cddefines.h"
00016 #include "physconst.h"
00017 #include "thirdparty.h"
00018 #include "hydro_bauman.h"
00019 
00020 struct t_mx
00021 {
00022         double        m;
00023         long int      x;
00024 };
00025 
00026 typedef struct t_mx mx;
00027 
00028 struct t_mxq
00029 {
00030         struct t_mx  mx;
00031         long int      q;
00032 };
00033 
00034 typedef struct t_mxq mxq;
00035 
00036 /************************************************************************************************/
00037 /*    these routines were written by Robert Bauman                                              */
00038 /*    The main reference for this section of code is                                            */
00039 /*    M. Brocklehurst                                                                           */
00040 /*    Mon. Note. R. astr. Soc. (1971) 153, 471-490                                              */
00041 /*                                                                                              */
00042 /*    The recombination coefficient is obtained from the                                        */
00043 /*    photoionization cross-section (see Burgess 1965).                                         */
00044 /*    We have:                                                                                  */
00045 /*                                                                                              */
00046 /*                  -                           -               l'=l+1                          */
00047 /*                 |  2 pi^(1/2) alpha^4 a_o^2 c |  2 y^(1/2)     ---                           */
00048 /* alpha(n,l,Z,Te)=|-----------------------------|  ---------  Z   >    I(n, l, l', t)          */
00049 /*                 |            3                |     n^2        ---                           */
00050 /*                  -                           -               l'=l-1                          */
00051 /*                                                                                              */
00052 /*      where                         OO                                                        */
00053 /*                                    -                                                         */
00054 /*                                   |                                                          */
00055 /*      I(n, l, l', t) = max(l,l') y | (1 + n^2 K^2)^2 Theta(n,l; K, l') exp( -K^2 y ) d(K^2)   */
00056 /*                                   |                                                          */
00057 /*                                  -                                                           */
00058 /*                                  0                                                           */
00059 /*                                                                                              */
00060 /*      Here K = k / Z                                                                          */
00061 /*                                                                                              */
00062 /*                                                                                              */
00063 /*      and                                                                                     */
00064 /*                                                                                              */
00065 /*                                                                                              */
00066 /*       y =   Z^2 Rhc/(k Te)= 15.778/t                                                         */
00067 /*                                                                                              */
00068 /*       where "t" is the scaled temperature, and "Te" is the electron Temperature              */
00069 /*                                                                                              */
00070 /*       t = Te/(10^4  Z^2)                                                                     */
00071 /*           Te in kelvin                                                                       */
00072 /*                                                                                              */
00073 /*                                           |              |^2                                 */
00074 /*         Theta(n,l; K, l') = (1 + n^2 K^2) | g(n,l; K,l') |                                   */
00075 /*                                           |              |                                   */
00076 /*                                                                                              */
00077 /*                                                                                              */
00078 /*                                                 ---- Not sure if this is K or k              */
00079 /*                                  OO            /     but think it is K                       */
00080 /*         where                    -            v                                              */
00081 /*                         K^2     |                                                            */
00082 /*         g(n,l; K,l') = -----    | R_nl(r) F_(K,l) r dr                                       */
00083 /*                         n^2     |                                                            */
00084 /*                                -                                                             */
00085 /*                                0                                                             */
00086 /*                                                                                              */
00087 /*                                                                                              */
00088 /*         -                           -                                                        */
00089 /*        |  2 pi^(1/2) alpha^4 a_o^2 c |                                                       */
00090 /*        |-----------------------------|                                                       */
00091 /*        |            3                |                                                       */
00092 /*         -                           -                                                        */
00093 /*                                                                                              */
00094 /*         = 2 * (3.141592654)^1/2 * (7.29735308e-3)^4                                          */
00095 /*                      * (0.529177249e-10)^2 * (2.99792458e8) / 3                              */
00096 /*                                                                                              */
00097 /*         = 2.8129897e-21                                                                      */
00098 /*         Mathematica gives 2.4764282710571237e-21                                             */
00099 /*                                                                                              */
00100 /*    The photoionization cross-section (see also Burgess 1965)                                 */
00101 /*     is given by;                                                                             */
00102 /*                   _               _        l'=l+1                                            */
00103 /*                  |4 PI alpha a_o^2 |  n^2   ---     max(l,l')                                */
00104 /*      a(Z';n,l,k)=|---------------- |  ---    >       --------- Theta(n,l; K, l')             */
00105 /*                  |       3         |  Z^2   ---     (2l + 1)                                 */
00106 /*                   _               _        l'=l-1                                            */
00107 /*                                                                                              */
00108 /*                                                                                              */
00109 /*      where  Theta(n,l; K, l') is defined above                                               */
00110 /************************************************************************************************/
00111 /************************************************************************************************/
00112 /*      For the transformation:                                                                 */
00113 /*                              Z -> rZ = Z'                                                    */
00114 /*                                                                                              */
00115 /*                              k -> rk = k'                                                    */
00116 /*      then                                                                                    */
00117 /*                                                                                              */
00118 /*                              K -> K = K'                                                     */
00119 /*                                                                                              */
00120 /*      and the cross-sections satisfy;                                                         */
00121 /*                                                1                                             */
00122 /*                               a(Z'; n,l,k') = --- a(Z; n,l,k)                                */
00123 /*                                               r^2                                            */
00124 /*                                                                                              */
00125 /*      Similiarly, the recombination coefficient satisfies                                    */
00126 /************************************************************************************************/
00127 
00128 /************************************************************************/
00129 /*  IN THE FOLLOWING WE HAVE  n > n'                                    */
00130 /************************************************************************/
00131 /* returns hydrogenic photoionization cross section in cm-2             */
00132 /* this routine is called by H_photo_cs when n is small */
00133 STATIC double H_photo_cs_lin(
00134         /* photon energy relative to threshold energy         */
00135         double rel_photon_energy,
00136         /* principal quantum number, 1 for ground             */
00137         long int n,
00138         /* angular momentum, 0 for s                          */
00139         long int l,
00140         /* charge, 1 for H+, 2 for He++, etc                  */
00141         long int iz );
00142 
00167 double H_photo_cs_log10(
00168         double photon_energy, 
00169         long int n, 
00170         long int l, 
00171         long int iz
00172 );
00173 
00174 /****************************************************************************/
00175 /*   Calculates the Einstein A's for hydrogen                               */
00176 STATIC double H_Einstein_A_lin(    /*  IN THE FOLLOWING WE HAVE  n > n'     */
00177         /* principal quantum number, 1 for ground, upper level      */
00178         long int n,
00179         /* angular momentum, 0 for s                                */
00180         long int l,
00181         /* principal quantum number, 1 for ground, lower level      */
00182         long int np,
00183         /* angular momentum, 0 for s                                */
00184         long int lp,
00185         /* Nuclear charge, 1 for H+, 2 for He++, etc                */
00186         long int iz
00187 );
00188 
00202 double H_Einstein_A_log10(
00203         long int n,
00204         long int l,
00205         long int np,
00206         long int lp,
00207         long int iz
00208 );
00209 
00230 inline double OscStr_f(
00231         long int n,
00232         long int l,
00233         long int np,
00234         long int lp,
00235         long int iz
00236 );
00237 
00258 inline double OscStr_f_log10(
00259         long int n,
00260         long int l,
00261         long int np,
00262         long int lp,
00263         long int iz
00264 );
00265 
00266 /******************************************************************************
00267  *   F21()                                                                
00268  *   Calculates the Hyper_Spherical_Function 2_F_1(a,b,c;y)                
00269  *   Here a,b, and c are (long int)                                       
00270  *   y is of type (double)                                            
00271  *   A is of type (char) and specifies whether the recursion is over      
00272  *   a or b. It has values A='a' or A='b'.                                
00273  ******************************************************************************/
00274 
00275 STATIC double F21(
00276         long int a,
00277         long int b,
00278         long int c,
00279         double y,
00280         char A
00281 );
00282 
00283 STATIC double F21i(
00284         long int a,
00285         long int b,
00286         long int c,
00287         double y,
00288         double *yV
00289 );
00290 
00291 /****************************************************************************************/
00292 /* hv calculates photon energy in ergs for n -> n' transitions for H and H-like ions    */
00293 /*  In the following, we have n > n'                                                    */
00294 /****************************************************************************************/
00295 
00296 inline double hv(
00297         /* returns energy in ergs */
00298         /* principal quantum number, 1 for ground, upper level     */
00299         long int n,
00300         /* principal quantum number, 1 for ground, lower level     */
00301         long int nprime,
00302         long int iz
00303 );
00304 
00305 /********************************************************************************/
00306 /*  In the following, we have n > n'                                            */
00307 /********************************************************************************/
00308 
00309 STATIC double fsff(
00310         /* principal quantum number, 1 for ground, upper level       */
00311         long int n,
00312         /* angular momentum, 0 for s                                 */
00313         long int l,
00314         /* principal quantum number, 1 for ground, lower level       */
00315         long int np
00316 );
00317 
00318 STATIC double log10_fsff(
00319         /* principal quantum number, 1 for ground, upper level       */
00320         long int n,
00321         /* angular momentum, 0 for s                                 */
00322         long int l,
00323         /* principal quantum number, 1 for ground, lower level       */
00324         long int np
00325 );
00326 
00327 /********************************************************************************/
00328 /*   F21_mx()                                                                   */
00329 /*   Calculates the Hyper_Spherical_Function 2_F_1(a,b,c;y)                     */
00330 /*   Here a,b, and c are (long int)                                             */
00331 /*   y is of type (double)                                                      */
00332 /*   A is of type (char) and specifies whether the recursion is over            */
00333 /*   a or b. It has values A='a' or A='b'.                                      */
00334 /********************************************************************************/
00335 
00336 STATIC mx F21_mx(
00337         long int a,
00338         long int b,
00339         long int c,
00340         double y,
00341         char A
00342 );
00343 
00344 STATIC mx F21i_log(
00345         long int a,
00346         long int b,
00347         long int c,
00348         double y,
00349         mxq *yV
00350 );
00351 
00365 inline double hri(
00366         long int n,
00367         long int l,
00368         long int np,                 
00369         long int lp,
00370         long int iz
00371 );
00372 
00385 inline double hri_log10(
00386         long int n,
00387         long int l,
00388         long int np,
00389         long int lp,
00390         long int iz
00391 );
00392 
00393 /******************************************************************************/
00394 /*  In the following, we have n > n'                                          */
00395 /******************************************************************************/
00396 STATIC double hrii(
00397         /* principal quantum number, 1 for ground, upper level     */
00398         long int n,
00399         /* angular momentum, 0 for s                               */
00400         long int l,
00401         /* principal quantum number, 1 for ground, lower level     */
00402         long int np,
00403         /* angular momentum, 0 for s                               */
00404         long int lp
00405 );
00406 
00407 STATIC double hrii_log(
00408         /* principal quantum number, 1 for ground, upper level       */
00409         long int n,
00410         /* angular momentum, 0 for s                                 */
00411         long int l,
00412         /* principal quantum number, 1 for ground, lower level       */
00413         long int np,
00414         /* angular momentum, 0 for s                                 */
00415         long int lp
00416 );
00417 
00418 STATIC double  bh(
00419         double k,
00420         long int n,
00421         long int l,
00422         double *rcsvV
00423 );
00424 
00425 STATIC double  bh_log(
00426         double k,
00427         long int n,
00428         long int l,
00429         mxq *rcsvV_mxq
00430 );
00431 
00432 STATIC double bhintegrand(
00433         double k,
00434         long int n,
00435         long int l,
00436         long int lp,
00437         double *rcsvV
00438 );
00439 
00440 STATIC double bhintegrand_log(
00441         double k,
00442         long int n,
00443         long int l,
00444         long int lp,
00445         mxq *rcsvV_mxq
00446 );
00447 
00448 STATIC double bhG(
00449         double K,
00450         long int n,
00451         long int l,
00452         long int lp,
00453         double *rcsvV
00454 );
00455 
00456 STATIC mx bhG_mx(
00457         double K,
00458         long int n,
00459         long int l,
00460         long int lp,
00461         mxq *rcsvV_mxq
00462 );
00463 
00464 STATIC double bhGp(
00465         long int q,
00466         double K,
00467         long int n,
00468         long int l,
00469         long int lp,
00470         double *rcsvV,
00471         double GK
00472 );
00473 
00474 STATIC mx bhGp_mx(
00475         long int q,
00476         double K,
00477         long int n,
00478         long int l,
00479         long int lp,
00480         mxq *rcsvV_mxq,
00481         const mx& GK_mx
00482 );
00483 
00484 STATIC double bhGm(
00485         long int q,
00486         double K,
00487         long int n,
00488         long int l,
00489         long int lp,
00490         double *rcsvV,
00491         double GK
00492 );
00493 
00494 STATIC mx bhGm_mx(
00495         long int q,
00496         double K,
00497         long int n,
00498         long int l,
00499         long int lp,
00500         mxq *rcsvV_mxq,
00501         const mx& GK_mx
00502 );
00503 
00504 STATIC double bhg(
00505         double K,
00506         long int n,
00507         long int l,
00508         long int lp,
00509         double *rcsvV
00510 );
00511 
00512 STATIC double bhg_log(
00513         double K,
00514         long int n,
00515         long int l,
00516         long int lp,
00517         mxq *rcsvV_mxq
00518 );
00519 
00520 inline void normalize_mx( mx& target );
00521 inline mx add_mx( const mx& a, const mx& b );
00522 inline mx sub_mx( const mx& a, const mx& b );
00523 inline mx mxify( double a );
00524 inline double unmxify( const mx& a_mx );
00525 inline mx mxify_log10( double log10_a );
00526 inline mx mult_mx( const mx& a, const mx& b );
00527 
00528 inline double local_product( double K , long int lp );
00529 inline double log10_prodxx( long int lp, double Ksqrd );
00530 
00531 /****************************************************************************************/
00532 /*  64 pi^4 (e a_o)^2    64 pi^4 (a_o)^2    e^2     1                      1            */
00533 /*  ----------------- = ----------------- -------- ----  = 7.5197711e-38 -----          */
00534 /*     3 h c^3                3  c^2       hbar c  2 pi                   sec           */
00535 /****************************************************************************************/
00536 
00537 static const double CONST_ONE = 32.*pow3(PI)*pow2(BOHR_RADIUS_CM)*FINE_STRUCTURE/(3.*pow2(SPEEDLIGHT));
00538 
00539 /************************************************************************/
00540 /* (4.0/3.0) * PI * FINE_STRUCTURE_CONSTANT * BOHRRADIUS * BOHRRADIUS   */
00541 /*                                                                      */
00542 /*                                                                      */
00543 /*      4 PI alpha a_o^2                                                */
00544 /*      ----------------                                                */
00545 /*             3                                                        */
00546 /*                                                                      */
00547 /*      where   alpha = Fine Structure Constant                         */
00548 /*              a_o   = Bohr Radius                                     */
00549 /*                                                                      */
00550 /*      = 3.056708^-02 (au Length)^2                                    */
00551 /*      = 8.56x10^-23 (meters)^2                                        */
00552 /*      = 8.56x10^-19 (cm)^2                                            */
00553 /*      = 8.56x10^+05 (barns)                                           */
00554 /*      = 0.856 (MB or megabarns)                                       */
00555 /*                                                                      */
00556 /*                                                                      */
00557 /*      1 barn = 10^-28 (meter)^2                                       */
00558 /************************************************************************/
00559 
00560 static const double PHYSICAL_CONSTANT_TWO = 4./3.*PI*FINE_STRUCTURE*pow2(BOHR_RADIUS_CM);
00561 
00562 /************************Start of program***************************/
00563 
00564 double H_photo_cs(
00565         /* incident photon energy relative to threshold       */
00566         double rel_photon_energy,
00567         /* principal quantum number, 1 for ground             */
00568         long int n,
00569         /* angular momentum, 0 for s                          */
00570         long int l,
00571         /* charge, 1 for H+, 2 for He++, etc                  */
00572         long int iz )
00573 {
00574         DEBUG_ENTRY( "H_photo_cs()" );
00575 
00576         double result;
00577         if( n<= 25 )
00578         {
00579                 result = H_photo_cs_lin( rel_photon_energy , n , l , iz );
00580         }
00581         else
00582         {
00583                 result = H_photo_cs_log10( rel_photon_energy , n , l , iz );
00584         }
00585         return result;
00586 }
00587 
00588 /************************************************************************/
00589 /*  IN THE FOLLOWING WE HAVE  n > n'                                    */
00590 /************************************************************************/
00591 
00592 /* returns hydrogenic photoionization cross section in cm-2             */
00593 /* this routine is called by H_photo_cs when n is small */
00594 STATIC double H_photo_cs_lin(
00595         /* photon energy relative to threshold energy         */
00596         double rel_photon_energy,
00597         /* principal quantum number, 1 for ground             */
00598         long int n,
00599         /* angular momentum, 0 for s                          */
00600         long int l,
00601         /* charge, 1 for H+, 2 for He++, etc                  */
00602         long int iz )
00603 {
00604         DEBUG_ENTRY( "H_photo_cs_lin()" );
00605 
00606         long int dim_rcsvV;
00607 
00608         /* >>chng 02 sep 15, make rcsvV always NPRE_FACGTORIAL+3 long */
00609         double rcsvV[NPRE_FACTORIAL+3];
00610         int i;
00611 
00612         double electron_energy;
00613         double result = 0.;
00614         double xn_sqrd = (double)(n*n);
00615         double z_sqrd = (double)(iz*iz);
00616         double Z = (double)iz;
00617         double K = 0.;  /* K = k / Z                            */
00618         double k = 0.;  /* k^2 = ejected-electron-energy (Ryd)  */
00619 
00620         /* expressions blow up at precisely threshold */
00621         if( rel_photon_energy < 1.+FLT_EPSILON )
00622         {
00623                 /* below or very close to threshold, return zero */
00624                 return 0.;
00625         }
00626 
00627         if( n < 1 || l >= n )
00628         {
00629                 fprintf(ioQQQ," The quantum numbers are impossible.\n");
00630                 cdEXIT(EXIT_FAILURE);
00631         }
00632 
00633         if( ((2*n) - 1) >= NPRE_FACTORIAL )
00634         {
00635                 fprintf(ioQQQ," This value of n is too large.\n");
00636                 cdEXIT(EXIT_FAILURE);
00637         }
00638 
00639         /* k^2 is the ejected photoelectron energy in ryd */
00640         /*electron_energy = SDIV( (photon_energy/ryd) - (z_sqrd/xn_sqrd) );*/
00641 
00642         electron_energy = (rel_photon_energy-1.) * (z_sqrd/xn_sqrd);
00643         k = sqrt( ( electron_energy ) );
00644 
00645         K = (k/Z);
00646 
00647         dim_rcsvV = (((n * 2) - 1) + 1);
00648 
00649         for( i=0; i<dim_rcsvV; ++i )
00650         {
00651                 rcsvV[i] = 0.;
00652         }
00653 
00654         /* rcsvV contains all results for quantum indices below n, l */
00655         result = PHYSICAL_CONSTANT_TWO * (xn_sqrd/z_sqrd) * bh( K, n, l, rcsvV );
00656 
00657         ASSERT( result != 0. );
00658         return result;
00659 }
00660 
00661 /*****************************************************************************/
00662 /*H_photo_cs_log10 returns hydrogenic photoionization cross section in cm-2
00663  * this routine is called by H_photo_cs when n is large */
00664 /*****************************************************************************/
00665 double H_photo_cs_log10(
00666         /* photon energy relative to threshold energy         */
00667         double rel_photon_energy,
00668         /* principal quantum number, 1 for ground            */
00669         long int n,
00670         /* angular momentum, 0 for s                         */
00671         long int l,
00672         /* charge, 1 for H+, 2 for He++, etc                 */
00673         long int iz
00674 )
00675 {
00676         DEBUG_ENTRY( "H_photo_cs_log10()" );
00677 
00678         long int dim_rcsvV_mxq;
00679 
00680         mxq *rcsvV_mxq = NULL;
00681 
00682         double electron_energy;
00683         double t1;
00684         double result = 0.;
00685         double xn_sqrd = (double)(n*n);
00686         double z_sqrd = (double)(iz*iz);
00687         double Z = (double)iz;
00688         double K = 0.;   /* K = k / Z                            */
00689         double k = 0.;   /* k^2 = ejected-electron-energy (Ryd)  */
00690 
00691         /* expressions blow up at precisely threshold */
00692         if( rel_photon_energy < 1.+FLT_EPSILON )
00693         {
00694                 /* below or very close to threshold, return zero */
00695                 fprintf( ioQQQ,"PROBLEM IN HYDRO_BAUMAN: rel_photon_energy, n, l, iz: %e\t%li\t%li\t%li\n",
00696                          rel_photon_energy,
00697                          n,
00698                          l,
00699                          iz );
00700                 cdEXIT(EXIT_FAILURE);
00701         }
00702         if( n < 1 || l >= n )
00703         {
00704                 fprintf(ioQQQ," The quantum numbers are impossible.\n");
00705                 cdEXIT(EXIT_FAILURE);
00706         }
00707 
00708         /* k^2 is the ejected photoelectron energy in ryd */
00709         /*electron_energy = SDIV( (photon_energy/ryd) - (z_sqrd/xn_sqrd) );*/
00710         electron_energy = (rel_photon_energy-1.) * (z_sqrd/xn_sqrd);
00711 
00712         k = sqrt( ( electron_energy ) );
00713         /* k^2 is the ejected photoelectron energy in ryd */
00714         /*k = sqrt( ( (photon_energy/ryd) - (z_sqrd/xn_sqrd) ) );*/
00715 
00716         K = (k/Z);
00717 
00718         dim_rcsvV_mxq = (((n * 2) - 1) + 1);
00719 
00720         /* create space */
00721         rcsvV_mxq = (mxq*)CALLOC( (size_t)dim_rcsvV_mxq, sizeof(mxq) );
00722 
00723         t1 = bh_log( K, n, l, rcsvV_mxq );
00724 
00725         ASSERT( t1 > 0. );
00726 
00727         t1 = MAX2( t1, 1.0e-250 );
00728 
00729         result = PHYSICAL_CONSTANT_TWO * (xn_sqrd/z_sqrd) * t1;
00730 
00731         free( rcsvV_mxq );
00732         if( result <= 0. )
00733         {
00734                 fprintf( ioQQQ, "PROBLEM: Hydro_Bauman...t1\t%e\n", t1 );
00735         }
00736         ASSERT( result > 0. );
00737         return result;
00738 }
00739 
00740 STATIC double bh(
00741         /* K = k / Z ::: k^2 = ejected-electron-energy (Ryd)    */
00742         double K,
00743         /* principal quantum number                             */
00744         long int n,
00745         /* angular  momentum quantum number                     */
00746         long int l,
00747         /* Temporary storage for intermediate                   */
00748         /*  results of the recursive routine                    */
00749         double *rcsvV
00750 )
00751 {
00752         DEBUG_ENTRY( "bh()" );
00753 
00754         long int lp = 0; /* l' */
00755         double sigma = 0.; /*      Sum in Brocklehurst eq. 3.13 */
00756 
00757         ASSERT( n > 0 );
00758         ASSERT( l >= 0 );
00759         ASSERT( n > l );
00760 
00761         if( l > 0 ) /* no lp=(l-1)  for  l=0 */
00762         {
00763                 for( lp = l - 1; lp <= l + 1; lp = lp + 2 )
00764                 {
00765                         sigma += bhintegrand( K, n, l, lp, rcsvV );
00766                 }
00767         }
00768         else
00769         {
00770                 lp = l + 1;
00771                 sigma = bhintegrand( K, n, l, lp, rcsvV );
00772         }
00773         ASSERT( sigma != 0. );
00774         return sigma;
00775 }
00776 
00777 STATIC double bh_log(
00778         /* K = k / Z ::: k^2 = ejected-electron-energy (Ryd)    */
00779         double K,
00780         /* principal quantum number                             */
00781         long int n,
00782         /* angular  momentum quantum number                     */
00783         long int l,
00784         /* Temporary storage for intermediate                   */
00785         mxq *rcsvV_mxq
00786         /*   results of the recursive routine                   */
00787 )
00788 {
00789         DEBUG_ENTRY( "bh_log()" );
00790 
00791         long int lp = 0; /* l' */
00792         double sigma = 0.; /*      Sum in Brocklehurst eq. 3.13 */
00793 
00794         ASSERT( n > 0 );
00795         ASSERT( l >= 0 );
00796         ASSERT( n > l );
00797 
00798         if( l > 0 ) /* no lp=(l-1)  for  l=0 */
00799         {
00800                 for( lp = l - 1; lp <= l + 1; lp = lp + 2 )
00801                 {
00802                         sigma += bhintegrand_log( K, n, l, lp, rcsvV_mxq );
00803                 }
00804         }
00805         else
00806         {
00807                 lp = l + 1;
00808                 sigma = bhintegrand_log( K, n, l, lp, rcsvV_mxq );
00809         }
00810         ASSERT( sigma != 0. );
00811         return sigma;
00812 }
00813 
00814 /********************************************************************************/
00815 /*      Here we calculate the integrand                                         */
00816 /*      (as a function of K, so                                                 */
00817 /*      we need a dK^2 -> 2K dK )                                               */
00818 /*      for  equation 3.14 of reference                                         */
00819 /*                                                                              */
00820 /*      M. Brocklehurst Mon. Note. R. astr. Soc. (1971) 153, 471-490            */
00821 /*                                                                              */
00822 /*      namely:                                                                 */
00823 /*                                                                              */
00824 /*      max(l,l')  (1 + n^2 K^2)^2 Theta(n,l; K, l') exp( -K^2 y ) d(K^2)       */
00825 /*                                                                              */
00826 /*      Note: the "y" is included in the code that called                       */
00827 /*      this function and we include here the n^2 from eq 3.13.                 */
00828 /********************************************************************************/
00829 
00830 STATIC double bhintegrand(
00831         /* K = k / Z ::: k^2 = ejected-electron-energy (Ryd) */
00832         double K,
00833         long int n,
00834         long int l,
00835         long int lp,
00836         /* Temporary storage for intermediate         */
00837         /*  results of the recursive routine          */
00838         double *rcsvV
00839 )
00840 {
00841         DEBUG_ENTRY( "bhintegrand()" );
00842 
00843         double Two_L_Plus_One = (double)(2*l + 1);
00844         double lg = (double)(l > lp ? l : lp);
00845 
00846         double n2 = (double)(n*n);
00847 
00848         double Ksqrd = (K*K);
00849 
00850         /**********************************************/
00851         /*                                            */
00852         /*    l>                                      */
00853         /*  ------    Theta(nl,Kl')                   */
00854         /*   2l+2                                     */
00855         /*                                            */
00856         /*                                            */
00857         /* Theta(nl,Kl') =                            */
00858         /*   (1+n^2K^2) * | g(nl,Kl')|^2              */
00859         /*                                            */
00860         /**********************************************/
00861 
00862         double d2 = 1. + n2*Ksqrd;
00863         double d5 = bhg( K, n, l, lp, rcsvV );
00864         double Theta = d2 * d5 * d5;
00865         double d7 = (lg/Two_L_Plus_One) * Theta;
00866 
00867         ASSERT( Two_L_Plus_One != 0. );
00868         ASSERT( Theta != 0. );
00869         ASSERT( Ksqrd != 0. );
00870         ASSERT( d2 != 0. );
00871         ASSERT( d5 != 0. );
00872         ASSERT( d7 != 0. );
00873         ASSERT( lp >= 0 );
00874         ASSERT( lg != 0. );
00875         ASSERT( n2 != 0. );
00876         ASSERT( n  > 0  );
00877         ASSERT( l  >= 0 );
00878         ASSERT( K  != 0. );
00879         return d7;
00880 }
00881 
00882 /************************************************************************************************/
00883 /*    The photoionization cross-section (see also Burgess 1965)                                 */
00884 /*     is given by;                                                                             */
00885 /*                   _               _        l'=l+1                                            */
00886 /*                  |4 PI alpha a_o^2 |  n^2   ---     max(l,l')                                */
00887 /*      a(Z';n,l,k)=|---------------- |  ---    >     ---------- Theta(n,l; K, l')              */
00888 /*                  |       3         |  Z^2   ---     (2l + 1)                                 */
00889 /*                   _               _        l'=l-1                                            */
00890 /*                                                                                              */
00891 /*                                                                                              */
00892 /*      where  Theta(n,l; K, l') is defined                                                     */
00893 /*                                                                                              */
00894 /*                                           |              |^2                                 */
00895 /*         Theta(n,l; K, l') = (1 + n^2 K^2) | g(n,l; K,l') |                                   */
00896 /*                                           |              |                                   */
00897 /*                                                                                              */
00898 /*                                                                                              */
00899 /*                                                 ---- Not sure if this is K or k              */
00900 /*                                  OO            /     but think it is K                       */
00901 /*         where                    -            v                                              */
00902 /*                         K^2     |                                                            */
00903 /*         g(n,l; K,l') = -----    | R_nl(r) F_(K,l) r dr                                       */
00904 /*                         n^2     |                                                            */
00905 /*                                -                                                             */
00906 /*                                0                                                             */
00907 /************************************************************************************************/
00908 
00909 STATIC double bhintegrand_log(
00910         double K,     /* K = k / Z ::: k^2 = ejected-electron-energy (Ryd) */
00911         long int n,
00912         long int l,
00913         long int lp,
00914         /* Temporary storage for intermediate         */
00915         /* results of the recursive routine           */
00916         mxq *rcsvV_mxq
00917 )
00918 {
00919         DEBUG_ENTRY( "bhintegrand_log()" );
00920 
00921         double d2 = 0.;
00922         double d5 = 0.;
00923         double d7 = 0.;
00924         double Theta = 0.;
00925         double n2 = (double)(n*n);
00926         double Ksqrd = (K*K);
00927         double Two_L_Plus_One = (double)(2*l + 1);
00928         double lg = (double)(l > lp ? l : lp);
00929 
00930         ASSERT( Ksqrd != 0. );
00931         ASSERT( K != 0. );
00932         ASSERT( lg != 0. );
00933         ASSERT( n2 != 0. );
00934         ASSERT( Two_L_Plus_One != 0. );
00935 
00936         ASSERT( n > 0);
00937         ASSERT( l >= 0);
00938         ASSERT( lp >= 0);
00939 
00940         /**********************************************/
00941         /*                                            */
00942         /*    l>                                      */
00943         /*  ------    Theta(nl,Kl')                   */
00944         /*   2l+2                                     */
00945         /*                                            */
00946         /*                                            */
00947         /* Theta(nl,Kl') =                            */
00948         /*   (1+n^2K^2) * | g(nl,Kl')|^2              */
00949         /*                                            */
00950         /**********************************************/
00951 
00952         d2 = ( 1. + n2 * (Ksqrd) );
00953 
00954         ASSERT( d2 != 0. );
00955 
00956         d5 = bhg_log( K, n, l, lp, rcsvV_mxq );
00957 
00958         d5 = MAX2( d5, 1.0E-150 );
00959         ASSERT( d5 != 0. );
00960 
00961         Theta = d2 * d5 * d5;
00962         ASSERT( Theta != 0. );
00963 
00964         d7 = (lg/Two_L_Plus_One) * Theta;
00965 
00966         ASSERT( d7 != 0. );
00967         return d7;
00968 }
00969 
00970 /****************************************************************************************/
00971 /*  *** bhG ***                                                                         */
00972 /*    Using various recursion relations                                                 */
00973 /*    (for l'=l+1)                                                                      */
00974 /*    equation: (3.23)                                                                  */
00975 /*    G(n,l-2; K,l-1) = [ 4n^2-4l^2+l(2l-1)(1+(n K)^2) ] G(n,l-1; K,l)                  */
00976 /*                      - 4n^2 (n^2-l^2)[1+(l+1)^2 K^2] G(n,l; K,l+1)                   */
00977 /*                                                                                      */
00978 /*    and (for l'=l-1)                                                                  */
00979 /*    equation: (3.24)                                                                  */
00980 /*    G(n,l-1; K,l-2) = [ 4n^2-4l^2 + l(2l-1)(1+(n K)^2) ] G(n,l; K,l-1)                */
00981 /*                      - 4n^2 (n^2-(l+1)^2)[ 1+(lK)^2 ] G(n,l; K,l+1)                  */
00982 /*                                                                                      */
00983 /*    the starting point for the recursion relations are;                               */
00984 /*    equation: (3.18)                                                                  */
00985 /*                     | pi |(1/2)   8n                                                 */
00986 /*     G(n,n-1; 0,n) = | -- |      ------- (4n)^n exp(-2n)                              */
00987 /*                     | 2  |      (2n-1)!                                              */
00988 /*                                                                                      */
00989 /*     equation: (3.20)                                                                 */
00990 /*                             exp(2n-2/K tan^(-1)(n K)                                 */
00991 /*     G(n,n-1; K,n) =  -----------------------------------------  *  G(n,n-1; 0,n)     */
00992 /*                      sqrt(1 - exp(-2 pi K)) * (1+(n K)^2)^(n+2)                      */
00993 /*                                                                                      */
00994 /*     equation: (3.20)                                                                 */
00995 /*     G(n,n-2; K,n-1) = (2n-2)(1+(n K)^2) n G(n,n-1; K,n)                              */
00996 /*                                                                                      */
00997 /*     equation: (3.21)                                                                 */
00998 /*                       (1+(n K)^2)                                                    */
00999 /*     G(n,n-1; K,n-2) = ----------- G(n,n-1; K,n)                                      */
01000 /*                           2n                                                         */
01001 /*                                                                                      */
01002 /*     equation: (3.22)                                                                 */
01003 /*     G(n,n-2; K,n-3) = (2n-1) (4+(n-1)(1+n^2 K^2)) G(n,n-1; K,n-2)                    */
01004 /****************************************************************************************/
01005 
01006 STATIC double bhG(
01007         double K,
01008         long int n,
01009         long int l,
01010         long int lp,
01011         /* Temporary storage for intermediate         */
01012         /* results of the recursive routine           */
01013         double *rcsvV
01014 )
01015 {
01016         DEBUG_ENTRY( "bhG()" );
01017 
01018         double n1 = (double)n;
01019         double n2 = (double)(n * n);
01020         double Ksqrd = K * K;
01021 
01022         double ld1 = factorial( 2*n - 1 );
01023         double ld2 = powi((double)(4*n), n);
01024         double ld3 = exp(-(double)(2 * n));
01025 
01026         /******************************************************************************
01027          *    ********G0*******                                                       *
01028          *                                                                            *
01029          *            | pi |(1/2)   8n                                                *
01030          *      G0 =  | -- |      ------- (4n)^n exp(-2n)                             *
01031          *            | 2  |      (2n-1)!                                             *
01032          ******************************************************************************/
01033 
01034         double G0 = SQRTPIBY2 * (8. * n1 * ld2 * ld3) / ld1;
01035 
01036         double d1 = sqrt( 1. - exp(( -2. *  PI )/ K ));
01037         double d2 = powi(( 1. + (n2 * Ksqrd)), ( n + 2 ));
01038         double d3 = atan( n1 * K );
01039         double d4 = ((2. / K) * d3);
01040         double d5 = (double)( 2 * n );
01041         double d6 = exp( d5 - d4 );
01042         double GK = ( d6 /( d1 * d2 ) ) * G0;
01043 
01044         /* l=l'-1 or l=l'+1 */
01045         ASSERT( (l == lp - 1) ||  (l == lp + 1) );
01046         ASSERT( K != 0. );
01047         ASSERT( Ksqrd != 0. );
01048         ASSERT( n1 != 0. );
01049         ASSERT( n2 != 0. );
01050         ASSERT( ((2*n) - 1) < 1755 );
01051         ASSERT( ((2*n) - 1) >= 0   );
01052         ASSERT( ld1 != 0. );
01053         ASSERT( (1.0 / ld1) != 0. );
01054         ASSERT( ld3 != 0. );
01055 
01056         ASSERT( K != 0. );
01057         ASSERT( d1 != 0. );
01058         ASSERT( d2 != 0. );
01059         ASSERT( d3 != 0. );
01060         ASSERT( d4 != 0. );
01061         ASSERT( d5 != 0. );
01062         ASSERT( d6 != 0. );
01063 
01064         ASSERT( G0 != 0. );
01065         ASSERT( GK != 0. );
01066 
01067         /******************************************************************************/
01068         /*    *****GK*****                                                            */
01069         /*                                                                            */
01070         /*                            exp(2n-2/K tan^(-1)(n K)                        */
01071         /*      G(n,n-1; K,n) =  ----------------------------------------- *  G0      */
01072         /*                       sqrt(1 - exp(-2 pi/ K)) * (1+(n K))^(n+2)            */
01073         /******************************************************************************/
01074 
01075         /*  GENERAL CASE: l = l'-1  */
01076         if( l == lp - 1 )
01077         {
01078                 double result = bhGm( l, K, n, l, lp, rcsvV, GK );
01079                 /* Here the m in bhGm() refers            */
01080                 /* to the minus sign(-) in l=l'-1         */
01081                 return result;
01082         }
01083 
01084         /*  GENERAL CASE: l = l'+1  */
01085         else if( l == lp + 1 )
01086         {
01087                 double result = bhGp( l, K, n, l, lp, rcsvV, GK );
01088                 /* Here the p in bhGp() refers            */
01089                 /* to the plus sign(+) in l=l'+1          */
01090                 return result;
01091         }
01092         else
01093         {
01094                 printf( "BadMagic: l and l' do NOT satisfy dipole requirements.\n\n" );
01095                 cdEXIT(EXIT_FAILURE);
01096         }
01097 }
01098 
01099 /*************log version********************************/
01100 STATIC mx bhG_mx(
01101         double K,
01102         long int n,
01103         long int l,
01104         long int lp,
01105         /* Temporary storage for intermediate        */
01106         /* results of the recursive routine          */
01107         mxq *rcsvV_mxq
01108 )
01109 {
01110         DEBUG_ENTRY( "bhG_mx()" );
01111 
01112         double log10_GK = 0.;
01113         double log10_G0 = 0.;
01114 
01115         double d1 = 0., d2 = 0., d3 = 0., d4 = 0., d5 = 0., d6 = 0.;
01116         double ld1 = 0., ld2 = 0., ld3 = 0., ld4 = 0., ld5 = 0., ld6 = 0.;
01117 
01118         double n1 = (double)n;
01119         double n2 = n1 * n1;
01120         double Ksqrd = K * K;
01121 
01122         mx GK_mx = {0.0,0};
01123 
01124         /* l=l'-1 or l=l'+1 */
01125         ASSERT( (l == lp - 1) ||  (l == lp + 1) );
01126         ASSERT( K != 0. );
01127         ASSERT( n1 != 0. );
01128         ASSERT( n2 != 0. );
01129         ASSERT( Ksqrd != 0. );
01130         ASSERT( ((2*n) - 1) >= 0   );
01131 
01132         /******************************/
01133         /*                 n          */
01134         /*                ---         */
01135         /*    log( n! ) =  >  log(j)  */
01136         /*                ---         */
01137         /*                j=1         */
01138         /******************************/
01139 
01140         /*************************************************************/
01141         /*                     | pi |(1/2)   8n                      */
01142         /*     G(n,n-1; 0,n) = | -- |      ------- (4n)^n exp(-2n)   */
01143         /*                     | 2  |      (2n-1)!                   */
01144         /*************************************************************/
01145 
01146         /******************************/
01147         /*                            */
01148         /*                            */
01149         /*      log10( (2n-1)! )      */
01150         /*                            */
01151         /*                            */
01152         /******************************/
01153 
01154         ld1 = lfactorial( 2*n - 1 );
01155         ASSERT( ld1 >= 0. );
01156 
01157         /**********************************************/
01158         /*            (4n)^n                          */
01159         /**********************************************/
01160         /*    log10( 4n^n ) = n log10( 4n )           */
01161         /**********************************************/
01162 
01163         ld2 = n1 * log10( 4. * n1 );
01164         ASSERT( ld2 >= 0. );
01165 
01166         /**********************************************/
01167         /*            exp(-2n)                        */
01168         /**********************************************/
01169         /*    log10( exp( -2n ) ) = (-2n) * log10(e)  */
01170         /**********************************************/
01171         ld3 = (-(2. * n1)) * (LOG10_E);
01172         ASSERT( ld3 <= 0. );
01173 
01174         /******************************************************************************/
01175         /*    ********G0*******                                                       */
01176         /*                                                                            */
01177         /*            | pi |(1/2)   8n                                                */
01178         /*      G0 =  | -- |      ------- (4n)^n exp(-2n)                             */
01179         /*            | 2  |      (2n-1)!                                             */
01180         /******************************************************************************/
01181 
01182         log10_G0 = log10(SQRTPIBY2 * 8. * n1) + ( (ld2 + ld3) - ld1);
01183 
01184         /******************************************************************************/
01185         /*    *****GK*****                                                            */
01186         /*                                                                            */
01187         /*                            exp(2n- (2/K) tan^(-1)(n K)  )                  */
01188         /*      G(n,n-1; K,n) =  ----------------------------------------- *  G0      */
01189         /*                       sqrt(1 - exp(-2 pi/ K)) * (1+(n K))^(n+2)            */
01190         /******************************************************************************/
01191 
01192         ASSERT( K != 0. );
01193 
01194         /**********************************************/
01195         /*  sqrt(1 - exp(-2 pi/ K))                   */
01196         /**********************************************/
01197         /*    log10(sqrt(1 - exp(-2 pi/ K))) =        */
01198         /*            (1/2) log10(1 - exp(-2 pi/ K))  */
01199         /**********************************************/
01200 
01201         d1 = (1. - exp(-(2. *  PI )/ K ));
01202         ld4 = (1./2.) * log10( d1 );
01203         ASSERT( K != 0. );
01204         ASSERT( d1 != 0. );
01205 
01206         /**************************************/
01207         /*         (1+(n K)^2)^(n+2)          */
01208         /**************************************/
01209         /* log10( (1+(n K)^2)^(n+2) ) =       */
01210         /*    (n+2) log10( (1 + (n K)^2 ) )   */
01211         /**************************************/
01212 
01213         d2 = ( 1. + (n2 * Ksqrd));
01214         ld5 = (n1 + 2.) * log10( d2 );
01215         ASSERT( d2 != 0. );
01216 
01217         ASSERT( ld5 >= 0. );
01218 
01219         /**********************************************/
01220         /*   exp(2n- (2/K)*tan^(-1)(n K)  )           */
01221         /**********************************************/
01222         /* log10( exp(2n- (2/K) tan^(-1)(n K)  ) =    */
01223         /*     (2n- (2/K)*tan^(-1)(n K) ) * Log10(e)  */
01224         /**********************************************/
01225 
01226         /*    tan^(-1)(n K) )         */
01227         d3 = atan( n1 * K );
01228         ASSERT( d3 != 0. );
01229 
01230         /*    (2/K)*tan^(-1)(n K) )   */
01231         d4 = (2. / K) * d3;
01232         ASSERT( d4 != 0. );
01233 
01234         /*            2n              */
01235         d5 = (double) ( 2. * n1 );
01236         ASSERT( d5 != 0. );
01237 
01238         /*  (2n-2/K tan^(-1)(n K))    */
01239         d6 = d5 - d4;
01240         ASSERT( d6 != 0. );
01241 
01242         /* log10( exp(2n- (2/K) tan^(-1)(n K)  )      */
01243         ld6 = LOG10_E * d6;
01244         ASSERT( ld6 != 0. );
01245 
01246         /******************************************************************************/
01247         /*    *****GK*****                                                            */
01248         /*                                                                            */
01249         /*                            exp(2n- (2/K) tan^(-1)(n K)  )                  */
01250         /*      G(n,n-1; K,n) =  ----------------------------------------- *  G0      */
01251         /*                       sqrt(1 - exp(-2 pi/ K)) * (1+(n K))^(n+2)            */
01252         /******************************************************************************/
01253 
01254         log10_GK = (ld6 -(ld4 + ld5)) + log10_G0;
01255         ASSERT( log10_GK != 0. );
01256 
01257         GK_mx = mxify_log10( log10_GK );
01258 
01259         /*  GENERAL CASE: l = l'-1  */
01260         if( l == lp - 1 )
01261         {
01262                 mx result_mx = bhGm_mx( l, K, n, l, lp, rcsvV_mxq , GK_mx );
01263                 /* Here the m in bhGm() refers           */
01264                 /* to the minus sign(-) in l=l'-1        */
01265                 return result_mx;
01266         }
01267         /*  GENERAL CASE: l = l'+1  */
01268         else if( l == lp + 1 )
01269         {
01270                 mx result_mx = bhGp_mx( l, K, n, l, lp, rcsvV_mxq , GK_mx );
01271                 /* Here the p in bhGp() refers           */
01272                 /* to the plus sign(+) in l=l'+1         */
01273                 return result_mx;
01274         }
01275         else
01276         {
01277                 printf( "BadMagic: l and l' do NOT satisfy dipole requirements.\n\n" );
01278                 cdEXIT(EXIT_FAILURE);
01279         }
01280 }
01281 
01282 /************************************************************************************************/
01283 /*  ***   bhGp.c   ***                                                                          */
01284 /*                                                                                              */
01285 /*    Here we calculate G(n,l; K,l') with the  recursive formula                                */
01286 /*    equation: (3.24)                                                                          */
01287 /*                                                                                              */
01288 /*    G(n,l-1; K,l-2) = [ 4n^2-4l^2 + l(2l+1)(1+(n K)^2) ] G(n,l; K,l-1)                        */
01289 /*                                                                                              */
01290 /*                      - 4n^2 (n^2-(l+1)^2)[ 1+(lK)^2 ] G(n,l+1; K,l)                          */
01291 /*                                                                                              */
01292 /*    Under the transformation l -> l + 1 this gives                                            */
01293 /*                                                                                              */
01294 /*    G(n,l+1-1; K,l+1-2) = [ 4n^2-4(l+1)^2 + (l+1)(2(l+1)+1)(1+(n K)^2) ] G(n,l+1; K,l+1-1)    */
01295 /*                                                                                              */
01296 /*                      - 4n^2 (n^2-((l+1)+1)^2)[ 1+((l+1)K)^2 ] G(n,l+1+1; K,l+1)              */
01297 /*                                                                                              */
01298 /*    or                                                                                        */
01299 /*                                                                                              */
01300 /*     G(n,l; K,l-1) = [ 4n^2-4(l+1)^2 + (l+1)(2l+3)(1+(n K)^2) ] G(n,l+1; K,l)                 */
01301 /*                                                                                              */
01302 /*                      - 4n^2 (n^2-(l+2)^2)[ 1+((l+1)K)^2 ] G(n,l+2; K,l+1)                    */
01303 /*                                                                                              */
01304 /*    from the reference                                                                        */
01305 /*    M. Brocklehurst                                                                           */
01306 /*    Mon. Note. R. astr. Soc. (1971) 153, 471-490                                              */
01307 /*                                                                                              */
01308 /*                                                                                              */
01309 /*  * This is valid for the case l=l'+1  *                                                      */
01310 /*  * CASE:     l = l'+1                 *                                                      */
01311 /*  * Here the p in bhGp() refers        *                                                      */
01312 /*  * to the Plus sign(+) in l=l'+1      *                                                      */
01313 /************************************************************************************************/
01314 
01315 STATIC double bhGp(
01316         long int q,
01317         double K,
01318         long int n,
01319         long int l,
01320         long int lp,
01321         /* Temporary storage for intermediate        */
01322         /*  results of the recursive routine         */
01323         double *rcsvV,
01324         double GK
01325 )
01326 {
01327         DEBUG_ENTRY( "bhGp()" );
01328 
01329         /* static long int rcsv_Level = 1;
01330            printf( "bhGp(): recursion level:\t%li\n",rcsv_Level++ ); */
01331 
01332         ASSERT( l == lp + 1 );
01333 
01334         long int rindx = 2*q;
01335 
01336         if( rcsvV[rindx] == 0. )
01337         {
01338                 /*  SPECIAL CASE:   n = l+1 = l'+2  */
01339                 if( q == n - 1 )
01340                 {
01341                         double Ksqrd = K * K;
01342                         double n2 = (double)(n*n);
01343 
01344                         double dd1 = (double)(2 * n);
01345                         double dd2 = ( 1. + ( n2 * Ksqrd));
01346 
01347                         /*                    (1+(n K)^2)                */
01348                         /*  G(n,n-1; K,n-2) = ----------- G(n,n-1; K,n)  */
01349                         /*                        2n                     */
01350                         double G1 = ((dd2 * GK) / dd1);
01351 
01352                         ASSERT( l == lp + 1 );
01353                         ASSERT( Ksqrd != 0. );
01354                         ASSERT( dd1 != 0. );
01355                         ASSERT( dd2 != 0. );
01356                         ASSERT( G1 != 0. );
01357 
01358                         rcsvV[rindx] = G1;
01359                         return G1;
01360                 }
01361                 /*  SPECIAL CASE:   n = l+2 = l'+3  */
01362                 else if( q == (n - 2) )
01363                 {
01364                         double Ksqrd = (K*K);
01365                         double n2 = (double)(n*n);
01366 
01367                         /*                                                               */
01368                         /* G(n,n-2; K,n-3) = (2n-1) (4+(n-1)(1+(n K)^2)) G(n,n-1; K,n-2) */
01369                         /*                                                               */
01370                         double dd1 = (double) (2 * n);
01371                         double dd2 = ( 1. + ( n2 * Ksqrd));
01372                         double G1 = ((dd2 * GK) / dd1);
01373 
01374                         /*                                                               */
01375                         /* G(n,n-2; K,n-3) = (2n-1) (4+(n-1)(1+(n K)^2)) G(n,n-1; K,n-2) */
01376                         /*                                                               */
01377                         double dd3 = (double)((2 * n) - 1);
01378                         double dd4 = (double)(n - 1);
01379                         double dd5 = (4. + (dd4 * dd2));
01380                         double G2 = (dd3 * dd5  * G1);
01381 
01382                         ASSERT( l == lp + 1 );
01383                         ASSERT( Ksqrd != 0. );
01384                         ASSERT( n2 != 0. );
01385                         ASSERT( dd1 != 0. );
01386                         ASSERT( dd2 != 0. );
01387                         ASSERT( dd3 != 0. );
01388                         ASSERT( dd4 != 0. );
01389                         ASSERT( dd5 != 0. );
01390                         ASSERT( G1 != 0. );
01391                         ASSERT( G2 != 0. );
01392 
01393                         rcsvV[rindx] = G2;
01394                         return G2;
01395                 }
01396                 /* The GENERAL CASE n > l + 2 */
01397                 else
01398                 {
01399                         /******************************************************************************/
01400                         /*  G(n,l; K,l-1) = [ 4n^2-4(l+1)^2 + (l+1)(2l+3)(1+(n K)^2) ] G(n,l+1; K,l)  */
01401                         /*                                                                            */
01402                         /*                      - 4n^2 (n^2-(l+2)^2)[ 1+((l+1)K)^2 ] G(n,l+2; K,l+1)  */
01403                         /*                                                                            */
01404                         /*            FROM   Eq. 3.24                                                 */
01405                         /*                                                                            */
01406                         /*  G(n,l-1; K,l-2) = [ 4n^2-4l+^2 + l(2l+1)(1+(n K)^2) ] G(n,l; K,l-1)       */
01407                         /*                                                                            */
01408                         /*                      - 4n^2 (n^2-(l+1)^2)[ 1+((lK)^2 ] G(n,l+1; K,l)       */
01409                         /******************************************************************************/
01410 
01411                         long int lp1 = (q + 1);
01412                         long int lp2 = (q + 2);
01413 
01414                         double Ksqrd = (K*K);
01415                         double n2 = (double)(n * n);
01416                         double lp1s = (double)(lp1 * lp1);
01417                         double lp2s = (double)(lp2 * lp2);
01418 
01419                         double d1 = (4. * n2);
01420                         double d2 = (4. * lp1s);
01421                         double d3 = (double)((lp1)*((2 * q) + 3));
01422                         double d4 = (1. + (n2 * Ksqrd));
01423                         double d5 = (d1 - d2 + (d3 * d4));
01424                         double d5_1 = d5 * bhGp( (q+1), K, n, l, lp, rcsvV, GK );
01425 
01426 
01427                         /*  G(n,l; K,l-1) = [ 4n^2-4(l+1)^2 + (l+1)(2l+3)(1+(n K)^2) ] G(n,l+1; K,l)   */
01428                         /*                                                                             */
01429                         /*                      - 4n^2 (n^2-(l+2)^2)[ 1+((l+1)K)^2 ] G(n,l+2; K,l+1)   */
01430 
01431                         double d6 = (n2 - lp2s);
01432                         double d7 = (1. + (lp1s * Ksqrd));
01433                         double d8 = (d1 * d6 * d7);
01434                         double d8_1 = d8 * bhGp( (q+2), K, n, l, lp, rcsvV, GK );
01435                         double d9 = (d5_1 - d8_1);
01436 
01437                         ASSERT( l == lp + 1 );
01438                         ASSERT( Ksqrd != 0. );
01439                         ASSERT( n2 != 0. );
01440 
01441                         ASSERT( lp1s != 0. );
01442                         ASSERT( lp2s != 0. );
01443 
01444                         ASSERT( d1 != 0. );
01445                         ASSERT( d2 != 0. );
01446                         ASSERT( d3 != 0. );
01447                         ASSERT( d4 != 0. );
01448                         ASSERT( d5 != 0. );
01449                         ASSERT( d6 != 0. );
01450                         ASSERT( d7 != 0. );
01451                         ASSERT( d8 != 0. );
01452                         ASSERT( d9 != 0. );
01453 
01454                         rcsvV[rindx] = d9;
01455                         return d9;
01456                 }
01457         }
01458         else
01459         {
01460                 ASSERT( rcsvV[rindx] != 0. );
01461                 return rcsvV[rindx];
01462         }
01463 }
01464 
01465 /***********************log version*******************************/
01466 STATIC mx bhGp_mx(
01467         long int q,
01468         double K,
01469         long int n,
01470         long int l,
01471         long int lp,
01472         /* Temporary storage for intermediate       */
01473         /* results of the recursive routine         */
01474         mxq *rcsvV_mxq,
01475         const mx& GK_mx
01476 )
01477 {
01478         DEBUG_ENTRY( "bhGp_mx()" );
01479 
01480         /* static long int rcsv_Level = 1;                                    */
01481         /*    printf( "bhGp(): recursion level:\t%li\n",rcsv_Level++ );       */
01482 
01483         ASSERT( l == lp + 1 );
01484 
01485         long int rindx = 2*q;
01486 
01487         if( rcsvV_mxq[rindx].q == 0 )
01488         {
01489                 /*  SPECIAL CASE:   n = l+1 = l'+2 */
01490                 if( q == n - 1 )
01491                 {
01492                         /******************************************************/
01493                         /*                    (1+(n K)^2)                     */
01494                         /*  G(n,n-1; K,n-2) = ----------- G(n,n-1; K,n)       */
01495                         /*                        2n                          */
01496                         /******************************************************/
01497 
01498                         double Ksqrd = (K * K);
01499                         double n2 = (double)(n*n);
01500 
01501                         double dd1 = (double) (2 * n);
01502                         double dd2 = ( 1. + ( n2 * Ksqrd));
01503                         double dd3 = dd2/dd1;
01504 
01505                         mx dd3_mx = mxify( dd3 );
01506                         mx G1_mx = mult_mx( dd3_mx, GK_mx);
01507 
01508                         normalize_mx( G1_mx );
01509 
01510                         ASSERT( l == lp + 1 );
01511                         ASSERT( Ksqrd != 0. );
01512                         ASSERT( n2 != 0. );
01513                         ASSERT( dd1 != 0. );
01514                         ASSERT( dd2 != 0. );
01515 
01516                         rcsvV_mxq[rindx].q = 1;
01517                         rcsvV_mxq[rindx].mx = G1_mx;
01518                         return G1_mx;
01519                 }
01520                 /*  SPECIAL CASE:   n = l+2 = l'+3 */
01521                 else if( q == (n - 2) )
01522                 {
01523                         /****************************************************************/
01524                         /*                                                              */
01525                         /* G(n,n-2; K,n-3) = (2n-1) (4+(n-1)(1+(n K)^2)) G(n,n-1; K,n-2)*/
01526                         /*                                                              */
01527                         /****************************************************************/
01528                         /*                    (1+(n K)^2)                               */
01529                         /*  G(n,n-1; K,n-2) = ----------- G(n,n-1; K,n)                 */
01530                         /*                        2n                                    */
01531                         /****************************************************************/
01532 
01533                         double Ksqrd = (K*K);
01534                         double n2 = (double)(n*n);
01535                         double dd1 = (double)(2 * n);
01536                         double dd2 = ( 1. + ( n2 * Ksqrd) );
01537                         double dd3 = (dd2/dd1);
01538                         double dd4 = (double) ((2 * n) - 1);
01539                         double dd5 = (double) (n - 1);
01540                         double dd6 = (4. + (dd5 * dd2));
01541                         double dd7 = dd4 * dd6;
01542 
01543                         /****************************************************************/
01544                         /*                                                              */
01545                         /* G(n,n-2; K,n-3) = (2n-1) (4+(n-1)(1+(n K)^2)) G(n,n-1; K,n-2)*/
01546                         /*                                                              */
01547                         /****************************************************************/
01548 
01549                         mx dd3_mx = mxify( dd3 );
01550                         mx dd7_mx = mxify( dd7 );
01551                         mx G1_mx = mult_mx( dd3_mx, GK_mx );
01552                         mx G2_mx = mult_mx( dd7_mx, G1_mx );
01553 
01554                         normalize_mx( G2_mx );
01555 
01556                         ASSERT( l == lp + 1 );
01557                         ASSERT( Ksqrd != 0. );
01558                         ASSERT( n2 != 0. );
01559                         ASSERT( dd1 != 0. );
01560                         ASSERT( dd2 != 0. );
01561                         ASSERT( dd3 != 0. );
01562                         ASSERT( dd4 != 0. );
01563                         ASSERT( dd5 != 0. );
01564                         ASSERT( dd6 != 0. );
01565                         ASSERT( dd7 != 0. );
01566 
01567                         rcsvV_mxq[rindx].q = 1;
01568                         rcsvV_mxq[rindx].mx = G2_mx;
01569                         return G2_mx;
01570                 }
01571                 /* The GENERAL CASE n > l + 2*/
01572                 else
01573                 {
01574                         /**************************************************************************************/
01575                         /*  G(n,l; K,l-1) = [ 4n^2-4(l+1)^2 + (l+1)(2l+3)(1+(n K)^2) ] G(n,l+1; K,l)          */
01576                         /*                                                                                    */
01577                         /*                      - 4n^2 (n^2-(l+2)^2)[ 1+((l+1)K)^2 ] G(n,l+2; K,l+1)          */
01578                         /*                                                                                    */
01579                         /*            FROM   Eq. 3.24                                                         */
01580                         /*                                                                                    */
01581                         /*  G(n,l-1; K,l-2) = [ 4n^2-4l+^2 + l(2l+1)(1+(n K)^2) ] G(n,l; K,l-1)               */
01582                         /*                                                                                    */
01583                         /*                      - 4n^2 (n^2-(l+1)^2)[ 1+((lK)^2 ] G(n,l+1; K,l)               */
01584                         /**************************************************************************************/
01585 
01586                         long int lp1 = (q + 1);
01587                         long int lp2 = (q + 2);
01588 
01589                         double Ksqrd = (K * K);
01590                         double n2 = (double)(n * n);
01591                         double lp1s = (double)(lp1 * lp1);
01592                         double lp2s = (double)(lp2 * lp2);
01593 
01594                         double d1 = (4. * n2);
01595                         double d2 = (4. * lp1s);
01596                         double d3 = (double)((lp1)*((2 * q) + 3));
01597                         double d4 = (1. + (n2 * Ksqrd));
01598                         /* [ 4n^2 - 4(l+1)^2 + (l+1)(2l+3)(1+(n K)^2) ]       */
01599                         double d5 = d1 - d2 + (d3 * d4);
01600 
01601                         /* (n^2-(l+2)^2)      */
01602                         double d6 = (n2 - lp2s);
01603 
01604                         /* [ 1+((l+1)K)^2 ]   */
01605                         double d7 = (1. + (lp1s * Ksqrd));
01606 
01607                         /* { 4n^2 (n^2-(l+1)^2)[ 1+((l+1) K)^2 ] }    */
01608                         double d8 = (d1 * d6 * d7);
01609 
01610                         /**************************************************************************************/
01611                         /*  G(n,l; K,l-1) = [ 4n^2 - 4(l+1)^2 + (l+1)(2l+3)(1+(n K)^2) ] G(n,l+1; K,l)        */
01612                         /*                                                                                    */
01613                         /*                      - 4n^2 (n^2-(l+2)^2)[ 1+((l+1)K)^2 ] G(n,l+2; K,l+1)          */
01614                         /**************************************************************************************/
01615 
01616                         mx d5_mx=mxify( d5 );
01617                         mx d8_mx=mxify( d8 );
01618 
01619                         mx t0_mx = bhGp_mx( (q+1), K, n, l, lp, rcsvV_mxq, GK_mx );
01620                         mx t1_mx = bhGp_mx( (q+2), K, n, l, lp, rcsvV_mxq, GK_mx );
01621 
01622                         mx d9_mx = mult_mx( d5_mx, t0_mx );
01623                         mx d10_mx = mult_mx( d8_mx, t1_mx );
01624 
01625                         mx result_mx = sub_mx( d9_mx, d10_mx );
01626                         normalize_mx( result_mx );
01627 
01628                         ASSERT( d1 != 0. );
01629                         ASSERT( d2 != 0. );
01630                         ASSERT( d3 != 0. );
01631                         ASSERT( d4 != 0. );
01632                         ASSERT( d5 != 0. );
01633                         ASSERT( d6 != 0. );
01634                         ASSERT( d7 != 0. );
01635                         ASSERT( d8 != 0. );
01636 
01637                         ASSERT( l == lp + 1 );
01638                         ASSERT( Ksqrd != 0. );
01639                         ASSERT( n2 != 0. );
01640                         ASSERT( lp1s != 0. );
01641                         ASSERT( lp2s != 0. );
01642 
01643                         rcsvV_mxq[rindx].q = 1;
01644                         rcsvV_mxq[rindx].mx = result_mx;
01645                         return result_mx;
01646                 }
01647         }
01648         else
01649         {
01650                 ASSERT( rcsvV_mxq[rindx].q != 0 );
01651                 rcsvV_mxq[rindx].q = 1;
01652                 return rcsvV_mxq[rindx].mx;
01653         }
01654 }
01655 
01656 /************************************************************************************************/
01657 /*  ***   bhGm.c  *** */
01658 /*                                                                                              */
01659 /*    Here we calculate G(n,l; K,l') with the  recursive formula                                */
01660 /*    equation: (3.23)                                                                          */
01661 /*                                                                                              */
01662 /*    G(n,l-2; K,l-1) = [ 4n^2-4l^2 + l(2l-1)(1+(n K)^2) ] G(n,l-1; K,l)                        */
01663 /*                                                                                              */
01664 /*                      - 4n^2 (n^2-l^2)[ 1 + (l+1)^2 K^2 ] G(n,l; K,l+1)                       */
01665 /*                                                                                              */
01666 /*    Under the transformation l -> l + 2 this gives                                            */
01667 /*                                                                                              */
01668 /*    G(n,l+2-2; K,l+2-1) = [ 4n^2-4(l+2)^2 + (l+2)(2(l+2)-1)(1+(n K)^2) ] G(n,l+2-1; K,l+2)    */
01669 /*                                                                                              */
01670 /*                      - 4n^2 (n^2-(l+2)^2)[ 1 + (l+2+1)^2 K^2 ] G(n,l+2; K,l+2+1)             */
01671 /*                                                                                              */
01672 /*                                                                                              */
01673 /*    or                                                                                        */
01674 /*                                                                                              */
01675 /*    G(n,l; K,l+1) = [ 4n^2-4(l+2)^2 + (l+2)(2l+3)(1+(n K)^2) ] G(n,l+1; K,l+2)                */
01676 /*                                                                                              */
01677 /*                      - 4n^2 (n^2-(l+2)^2)[ 1 + (l+3)^2 K^2 ] G(n,l+2; K,l+3)                 */
01678 /*                                                                                              */
01679 /*                                                                                              */
01680 /*    from the reference                                                                        */
01681 /*    M. Brocklehurst                                                                           */
01682 /*    Mon. Note. R. astr. Soc. (1971) 153, 471-490                                              */
01683 /*                                                                                              */
01684 /*                                                                                              */
01685 /*  * This is valid for the case l=l'-1 *                                                       */
01686 /*  * CASE:     l = l'-1                *                                                       */
01687 /*  * Here the p in bhGm() refers       *                                                       */
01688 /*  * to the Minus sign(-) in l=l'-1    *                                                       */
01689 /************************************************************************************************/
01690 
01691 #if defined (__ICC) && defined(__amd64) && __INTEL_COMPILER < 1000
01692 #pragma optimize("", off)
01693 #endif
01694 STATIC double bhGm(
01695         long int q,
01696         double K,
01697         long int n,
01698         long int l,
01699         long int lp,
01700         double *rcsvV,
01701         double GK
01702 )
01703 {
01704         DEBUG_ENTRY( "bhGm()" );
01705 
01706         ASSERT( l == lp - 1 );
01707         ASSERT( l < n );
01708 
01709         long int rindx = 2*q+1;
01710 
01711         if( rcsvV[rindx] == 0. )
01712         {
01713                 /*  CASE:     l = n - 1       */
01714                 if( q == n - 1 )
01715                 {
01716                         ASSERT( l == lp - 1 );
01717                         rcsvV[rindx] = GK;
01718                         return GK;
01719                 }
01720                 /*  CASE:     l = n - 2       */
01721                 else if( q == n - 2 )
01722                 {
01723                         double dd1 = 0.;
01724                         double dd2 = 0.;
01725 
01726                         double G2 = 0.;
01727 
01728                         double Ksqrd = 0.;
01729                         double n1 = 0.;
01730                         double n2 = 0.;
01731 
01732                         ASSERT(l == lp - 1);
01733 
01734                         /* K^2 */
01735                         Ksqrd = K * K;
01736                         ASSERT( Ksqrd != 0. );
01737 
01738                         /* n */
01739                         n1 = (double)n;
01740                         ASSERT( n1 != 0. );
01741 
01742                         /* n^2 */
01743                         n2 = (double)(n*n);
01744                         ASSERT( n2 != 0. );
01745 
01746                         /*     equation: (3.20)                         */
01747                         /*     G(n,n-2; K,n-1) =                        */
01748                         /*            (2n-1)(1+(n K)^2) n G(n,n-1; K,n) */
01749                         dd1 = (double) ((2 * n) - 1);
01750                         ASSERT( dd1 != 0. );
01751 
01752                         dd2 = (1. + (n2 * Ksqrd));
01753                         ASSERT( dd2 != 0. );
01754 
01755                         G2 = dd1 * dd2 * n1 * GK;
01756                         ASSERT( G2 != 0. );
01757 
01758                         rcsvV[rindx] = G2;
01759                         ASSERT( G2 != 0. );
01760                         return G2;
01761                 }
01762                 else
01763                 {
01764                         long int lp2 = (q + 2);
01765                         long int lp3 = (q + 3);
01766 
01767                         double lp2s = (double)(lp2 * lp2);
01768                         double lp3s = (double)(lp3 * lp3);
01769 
01770                         /******************************************************************************/
01771                         /* G(n,l; K,l+1) = [ 4n^2-4(l+2)^2 + (l+2)(2l+3)(1+(n K)^2) ] G(n,l+1; K,l+2) */
01772                         /*                                                                            */
01773                         /*                    - 4n^2 (n^2-(l+2)^2)[ 1+((l+3)^2 K^2) ] G(n,l+2; K,l+3) */
01774                         /*                                                                            */
01775                         /*                                                                            */
01776                         /*            FROM   Eq. 3.23                                                 */
01777                         /*                                                                            */
01778                         /* G(n,l-2; K,l-1) = [ 4n^2-4l^2 + (l+2)(2l-1)(1+(n K)^2) ] G(n,l-1; K,l)     */
01779                         /*                                                                            */
01780                         /*                   - 4n^2 (n^2-l^2)[ 1 + (l+1)^2 K^2 ] G(n,l; K,l+1)        */
01781                         /******************************************************************************/
01782 
01783                         double Ksqrd = (K*K);
01784                         double n2 = (double)(n*n);
01785                         double d1 = (4. * n2);
01786                         double d2 = (4. * lp2s);
01787                         double d3 = (double)(lp2)*((2*q)+3);
01788                         double d4 = (1. + (n2 * Ksqrd));
01789                         /* 4n^2-4(l+2)^2 + (l+2)(2l+3)(1+(n K)^2) */
01790                         double d5 = d1 - d2 + (d3 * d4);
01791 
01792                         /******************************************************************************/
01793                         /* G(n,l; K,l+1) = [ 4n^2-4(l+2)^2 + (l+2)(2l+3)(1+(n K)^2) ] G(n,l+1; K,l+2) */
01794                         /*                                                                            */
01795                         /*                   - 4n^2 (n^2-(l+2)^2)[ 1 + (l+3)^2 K^2 ] G(n,l+2; K,l+3)  */
01796                         /******************************************************************************/
01797 
01798                         double d6 = (n2 - lp2s);
01799                         /* [ 1+((l+3)K)^2 ]  */
01800                         double d7 = (1. + (lp3s * Ksqrd));
01801                         /* 4n^2 (n^2-(l+2)^2)[ 1 + (l+3)^2 K^2 ] */
01802                         double d8 = d1 * d6 * d7;
01803                         double d9 = d5 * bhGm( (q+1), K, n, l, lp, rcsvV, GK );
01804                         double d10 = d8 * bhGm( (q+2), K, n, l, lp, rcsvV, GK );
01805                         double d11 = d9 - d10;
01806 
01807                         ASSERT( l == lp - 1 );
01808                         ASSERT( lp2s != 0. );
01809                         ASSERT( Ksqrd != 0. );
01810                         ASSERT( n2 != 0. );
01811                         ASSERT( d1 != 0. );
01812                         ASSERT( d2 != 0. );
01813                         ASSERT( d3 != 0. );
01814                         ASSERT( d4 != 0. );
01815                         ASSERT( d5 != 0. );
01816                         ASSERT( d6 != 0. );
01817                         ASSERT( d7 != 0. );
01818                         ASSERT( d8 != 0. );
01819                         ASSERT( d9 != 0. );
01820                         ASSERT( d10 != 0. );
01821                         ASSERT( lp3s != 0. );
01822 
01823                         rcsvV[rindx] = d11;
01824                         return d11;
01825                 }
01826         }
01827         else
01828         {
01829                 ASSERT(  rcsvV[rindx] != 0. );
01830                 return rcsvV[rindx];
01831         }
01832 }
01833 #if defined (__ICC) && defined(__amd64) && __INTEL_COMPILER < 1000
01834 #pragma optimize("", on)
01835 #endif
01836 
01837 /************************log version***********************************/
01838 STATIC mx bhGm_mx(
01839         long int q,
01840         double K,
01841         long int n,
01842         long int l,
01843         long int lp,
01844         mxq *rcsvV_mxq,
01845         const mx& GK_mx
01846 )
01847 {
01848         DEBUG_ENTRY( "bhGm_mx()" );
01849 
01850         /*static long int rcsv_Level = 1;                                     */
01851         /*printf( "bhGm(): recursion level:\t%li\n",rcsv_Level++ );           */
01852 
01853         ASSERT( l == lp - 1 );
01854         ASSERT( l < n );
01855 
01856         long int rindx = 2*q+1;
01857 
01858         if( rcsvV_mxq[rindx].q == 0 )
01859         {
01860                 /*  CASE:     l = n - 1      */
01861                 if( q == n - 1 )
01862                 {
01863                         mx result_mx = GK_mx;
01864                         normalize_mx( result_mx );
01865 
01866                         rcsvV_mxq[rindx].q = 1;
01867                         rcsvV_mxq[rindx].mx = result_mx;
01868 
01869                         ASSERT(l == lp - 1);
01870                         return result_mx;
01871                 }
01872                 /*  CASE:     l = n - 2      */
01873                 else if( q == n - 2 )
01874                 {
01875                         double Ksqrd = (K * K);
01876                         double n1 = (double)n;
01877                         double n2 = (double) (n*n);
01878                         double dd1 = (double)((2 * n) - 1);
01879                         double dd2 = (1. + (n2 * Ksqrd));
01880                         /*(2n-1)(1+(n K)^2) n*/
01881                         double dd3 = (dd1*dd2*n1); 
01882 
01883                         /******************************************************/
01884                         /*     G(n,n-2; K,n-1) =                              */
01885                         /*            (2n-1)(1+(n K)^2) n G(n,n-1; K,n)       */
01886                         /******************************************************/
01887 
01888                         mx dd3_mx = mxify( dd3 );
01889                         mx G2_mx = mult_mx( dd3_mx, GK_mx );
01890 
01891                         normalize_mx( G2_mx );
01892 
01893                         ASSERT( l == lp - 1);
01894                         ASSERT( n1 != 0. );
01895                         ASSERT( n2 != 0. );
01896                         ASSERT( dd1 != 0. );
01897                         ASSERT( dd2 != 0. );
01898                         ASSERT( dd3 != 0. );
01899                         ASSERT( Ksqrd != 0. );
01900 
01901                         rcsvV_mxq[rindx].q = 1;
01902                         rcsvV_mxq[rindx].mx = G2_mx;
01903                         return G2_mx;
01904                 }
01905                 else
01906                 {
01907                         /******************************************************************************/
01908                         /* G(n,l; K,l+1) = [ 4n^2-4(l+2)^2 + (l+2)(2l+3)(1+(n K)^2) ] G(n,l+1; K,l+2) */
01909                         /*                                                                            */
01910                         /*                    - 4n^2 (n^2-(l+2)^2)[ 1+((l+3)^2 K^2) ] G(n,l+2; K,l+3) */
01911                         /*                                                                            */
01912                         /*                                                                            */
01913                         /*            FROM   Eq. 3.23                                                 */
01914                         /*                                                                            */
01915                         /* G(n,l-2; K,l-1) = [ 4n^2-4l^2 + (l+2)(2l-1)(1+(n K)^2) ] G(n,l-1; K,l)     */
01916                         /*                                                                            */
01917                         /*                   - 4n^2 (n^2-l^2)[ 1 + (l+1)^2 K^2 ] G(n,l; K,l+1)        */
01918                         /******************************************************************************/
01919 
01920                         long int lp2 = (q + 2);
01921                         long int lp3 = (q + 3);
01922 
01923                         double lp2s = (double)(lp2 * lp2);
01924                         double lp3s = (double)(lp3 * lp3);
01925                         double n2 = (double)(n*n);
01926                         double Ksqrd = (K * K);
01927 
01928                         /******************************************************/
01929                         /*    [ 4n^2-4(l+2)^2 + (l+2)(2l+3)(1+(n K)^2) ]      */
01930                         /******************************************************/
01931 
01932                         double d1 = (4. * n2);
01933                         double d2 = (4. * lp2s);
01934                         double d3 = (double)(lp2)*((2*q)+3);
01935                         double d4 = (1. + (n2 * Ksqrd));
01936                         /* 4n^2-4(l+2)^2 + (l+2)(2l+3)(1+(n K)^2)           */
01937                         double d5 = d1 - d2 + (d3 * d4);
01938 
01939                         mx d5_mx=mxify(d5);
01940 
01941                         /******************************************************/
01942                         /*        4n^2 (n^2-(l+2)^2)[ 1+((l+3)^2 K^2) ]       */
01943                         /******************************************************/
01944 
01945                         double d6 = (n2 - lp2s);
01946                         double d7 = (1. + (lp3s * Ksqrd));
01947                         /* 4n^2 (n^2-(l+2)^2)[ 1 + (l+3)^2 K^2 ]            */
01948                         double d8 = d1 * d6 * d7;
01949 
01950                         mx d8_mx = mxify(d8);
01951 
01952                         /******************************************************************************/
01953                         /* G(n,l; K,l+1) = [ 4n^2-4(l+2)^2 + (l+2)(2l+3)(1+(n K)^2) ] G(n,l+1; K,l+2) */
01954                         /*                                                                            */
01955                         /*                   - 4n^2 (n^2-(l+2)^2)[ 1 + (l+3)^2 K^2 ] G(n,l+2; K,l+3)  */
01956                         /******************************************************************************/
01957 
01958                         mx d9_mx = bhGm_mx( (q+1), K, n, l, lp, rcsvV_mxq, GK_mx );
01959                         mx d10_mx = bhGm_mx( (q+2), K, n, l, lp, rcsvV_mxq, GK_mx );
01960                         mx d11_mx = mult_mx( d5_mx, d9_mx );
01961                         mx d12_mx = mult_mx( d8_mx, d10_mx);
01962                         mx result_mx = sub_mx( d11_mx , d12_mx );
01963                         rcsvV_mxq[rindx].q = 1;
01964                         rcsvV_mxq[rindx].mx = result_mx;
01965 
01966                         ASSERT(l == lp - 1);
01967                         ASSERT(n2 != 0. );
01968                         ASSERT(lp2s != 0.);
01969                         ASSERT( lp3s != 0.);
01970                         ASSERT(Ksqrd != 0.);
01971 
01972                         ASSERT(d1 != 0.);
01973                         ASSERT(d2 != 0.);
01974                         ASSERT(d3 != 0.);
01975                         ASSERT(d4 != 0.);
01976                         ASSERT(d5 != 0.);
01977                         ASSERT(d6 != 0.);
01978                         ASSERT(d7 != 0.);
01979                         ASSERT(d8 != 0.);
01980                         return result_mx;
01981                 }
01982         }
01983         else
01984         {
01985                 ASSERT(  rcsvV_mxq[rindx].q != 0 );
01986                 return rcsvV_mxq[rindx].mx;
01987         }
01988 }
01989 
01990 /****************************************************************************************/
01991 /*                                                                                      */
01992 /*      bhg.c                                                                           */
01993 /*                                                                                      */
01994 /*      From reference;                                                                 */
01995 /*      M. Brocklehurst                                                                 */
01996 /*      Mon. Note. R. astr. Soc. (1971) 153, 471-490                                    */
01997 /*                                                                                      */
01998 /*                                                                                      */
01999 /*      We wish to compute the following function,                                      */
02000 /*                                                                                      */
02001 /*    equation: (3.17)                                                                  */
02002 /*                 -           s=l'              - (1/2)                                */
02003 /*                |  (n+l)!   -----               |                                     */
02004 /*    g(nl, Kl) = | --------   | |  (1 + s^2 K^2) |    *  (2n)^(l-n) G(n,l; K,l')       */
02005 /*                | (n-l-1)!   | |                |                                     */
02006 /*                 -           s=0               -                                      */
02007 /*                                                                                      */
02008 /*    Using various recursion relations (for l'=l+1)                                    */
02009 /*                                                                                      */
02010 /*    equation: (3.23)                                                                  */
02011 /*    G(n,l-2; K,l-1) = [ 4n^2-4l^2+l(2l-1)(1+(n K)^2) ] G(n,l-1; K,l)                  */
02012 /*                                                                                      */
02013 /*                      - 4n^2 (n^2-l^2)[1+(l+1)^2 K^2] G(n,l; K,l+1)                   */
02014 /*                                                                                      */
02015 /*    and (for l'=l-1)                                                                  */
02016 /*                                                                                      */
02017 /*    equation: (3.24)                                                                  */
02018 /*    G(n,l-1; K,l-2) = [ 4n^2-4l^2 + l(2l-1)(1+(n K)^2) ] G(n,l; K,l-1)                */
02019 /*                                                                                      */
02020 /*                      - 4n^2 (n^2-(l+1)^2)[ 1+(lK)^2 ] G(n,l; K,l+1)                  */
02021 /*                                                                                      */
02022 /*                                                                                      */
02023 /*    the starting point for the recursion relations are:                               */
02024 /*                                                                                      */
02025 /*                                                                                      */
02026 /*    equation (3.18):                                                                  */
02027 /*                                                                                      */
02028 /*                     | pi |(1/2)   8n                                                 */
02029 /*     G(n,n-1; 0,n) = | -- |      ------- (4n)^2 exp(-2n)                              */
02030 /*                     | 2  |      (2n-1)!                                              */
02031 /*                                                                                      */
02032 /*     equation (3.20):                                                                 */
02033 /*                                                                                      */
02034 /*                          exp(2n-2/K tan^(-1)(n K)                                    */
02035 /*     G(n,n-1; K,n) =  ---------------------------------------                         */
02036 /*                      sqrt(1 - exp(-2 pi/ K)) * (1+(n K)^(n+2)                        */
02037 /*                                                                                      */
02038 /*                                                                                      */
02039 /*                                                                                      */
02040 /*     equation (3.20):                                                                 */
02041 /*     G(n,n-2; K,n-1) = (2n-2)(1+(n K)^2) n G(n,n-1; K,n)                              */
02042 /*                                                                                      */
02043 /*                                                                                      */
02044 /*     equation (3.21):                                                                 */
02045 /*                                                                                      */
02046 /*                       (1+(n K)^2)                                                    */
02047 /*     G(n,n-1; K,n-2) = ----------- G(n,n-1; K,n)                                      */
02048 /*                           2n                                                         */
02049 /****************************************************************************************/
02050 
02051 STATIC double bhg(
02052         double K,
02053         long int n,
02054         long int l,
02055         long int lp,
02056         /* Temporary storage for intermediate      */
02057         /*   results of the recursive routine      */
02058         double *rcsvV
02059 )
02060 {
02061         DEBUG_ENTRY( "bhg()" );
02062 
02063         double ld1 = factorial( n + l );
02064         double ld2 = factorial( n - l - 1 );
02065         double ld3 = (ld1 / ld2);
02066 
02067         double partprod = local_product( K , lp );
02068 
02069         /**************************************************************************************/
02070         /*    equation: (3.17)                                                                */
02071         /*                 -           s=l'              - (1/2)                              */
02072         /*                |  (n+l)!   -----               |                                   */
02073         /*    g(nl, Kl) = | --------   | |  (1 + s^2 K^2) |    *  (2n)^(l-n) G(n,l; K,l')     */
02074         /*                | (n-l-1)!   | |                |                                   */
02075         /*                 -           s=0               -                                    */
02076         /**************************************************************************************/
02077 
02078         /**********************************************/
02079         /*      -           s=l'              - (1/2) */
02080         /*     |  (n+l)!   -----               |      */
02081         /*     | --------   | |  (1 + s^2 K^2) |      */
02082         /*     | (n-l-1)!   | |                |      */
02083         /*      -           s=0               -       */
02084         /**********************************************/
02085 
02086         double d2 = sqrt( ld3 * partprod );
02087         double d3 = powi( (2 * n) , (l - n) );
02088         double d4 = bhG( K, n, l, lp, rcsvV );
02089         double d5 = (d2 * d3);
02090         double d6 = (d5 * d4);
02091 
02092         ASSERT(K != 0.);
02093         ASSERT( (n+l) >= 1 );
02094         ASSERT( ((n-l)-1) >= 0 );
02095 
02096         ASSERT( partprod != 0. );
02097 
02098         ASSERT( ld1 != 0. );
02099         ASSERT( ld2 != 0. );
02100         ASSERT( ld3 != 0. );
02101 
02102         ASSERT( d2 != 0. );
02103         ASSERT( d3 != 0. );
02104         ASSERT( d4 != 0. );
02105         ASSERT( d5 != 0. );
02106         ASSERT( d6 != 0. );
02107         return d6;
02108 }
02109 
02110 /********************log version**************************/
02111 STATIC double bhg_log(
02112         double K,
02113         long int n,
02114         long int l,
02115         long int lp,
02116         /* Temporary storage for intermediate      */
02117         /*   results of the recursive routine      */
02118         mxq *rcsvV_mxq
02119 )
02120 {
02121         /**************************************************************************************/
02122         /*    equation: (3.17)                                                                */
02123         /*                 -           s=l'              - (1/2)                              */
02124         /*                |  (n+l)!   -----               |                                   */
02125         /*    g(nl, Kl) = | --------   | |  (1 + s^2 K^2) |    *  (2n)^(l-n) G(n,l; K,l')     */
02126         /*                | (n-l-1)!   | |                |                                   */
02127         /*                 -           s=0               -                                    */
02128         /**************************************************************************************/
02129 
02130         DEBUG_ENTRY( "bhg_log()" );
02131 
02132         double d1 = (double)(2*n);
02133         double d2 = (double)(l-n);
02134         double Ksqrd = (K*K);
02135 
02136         /**************************************************************************************/
02137         /*                                                                                    */
02138         /*          |  (n+l)!  |                                                              */
02139         /*    log10 | -------- | = log10((n+1)!) - log10((n-l-1)!)                            */
02140         /*          | (n-l-1)! |                                                              */
02141         /*                                                                                    */
02142         /**************************************************************************************/
02143 
02144         double ld1 = lfactorial( n + l );
02145         double ld2 = lfactorial( n - l - 1 );
02146 
02147         /**********************************************************************/
02148         /*        |  s=l'                |     s=l'                           */
02149         /*        | -----                |     ---                            */
02150         /*  log10 |  | |  (1 + s^2 K^2)  | =    >    log10((1 + s^2 K^2))     */
02151         /*        |  | |                 |     ---                            */
02152         /*        |  s=0                 |     s=0                            */
02153         /**********************************************************************/
02154 
02155         double ld3 = log10_prodxx( lp, Ksqrd );
02156 
02157         /**********************************************/
02158         /*      -           s=l'              - (1/2) */
02159         /*     |  (n+l)!   -----               |      */
02160         /*     | --------   | |  (1 + s^2 K^2) |      */
02161         /*     | (n-l-1)!   | |                |      */
02162         /*      -           s=0               -       */
02163         /**********************************************/
02164 
02165         /***********************************************************************/
02166         /*                                                                     */
02167         /*            |  -           s=l'              - (1/2) |               */
02168         /*            | |  (n+l)!   -----               |      |               */
02169         /*       log10| | --------   | |  (1 + s^2 K^2) |      | ==            */
02170         /*            | | (n-l-1)!   | |                |      |               */
02171         /*            |  -           s=0               -       |               */
02172         /*                                                                     */
02173         /*              |                           |  s=l'               |  | */
02174         /*              |      |  (n+l)!  |         | -----               |  | */
02175         /*       (1/2)* |log10 | -------- | + log10 |  | |  (1 + s^2 K^2) |  | */
02176         /*              |      | (n-l-1)! |         |  | |                |  | */
02177         /*              |                           |  s=0                |  | */
02178         /*                                                                     */
02179         /***********************************************************************/
02180 
02181         double ld4 = (1./2.) * ( ld3 + ld1 - ld2 );
02182 
02183         /**********************************************/
02184         /*                   (2n)^(l-n)               */
02185         /**********************************************/
02186         /*    log10( 2n^(L-n) ) = (L-n) log10( 2n )   */
02187         /**********************************************/
02188 
02189         double ld5 = d2 * log10( d1 );
02190 
02191         /**************************************************************************************/
02192         /*    equation: (3.17)                                                                */
02193         /*                 -           s=l'              - (1/2)                              */
02194         /*                |  (n+l)!   -----               |                                   */
02195         /*    g(nl, Kl) = | --------   | |  (1 + s^2 K^2) |    *  (2n)^(l-n) * G(n,l; K,l')   */
02196         /*                | (n-l-1)!   | |                |                                   */
02197         /*                 -           s=0               -                                    */
02198         /**************************************************************************************/
02199 
02200         /****************************************************/
02201         /*                                                  */
02202         /*  -           s=l'              - (1/2)           */
02203         /* |  (n+l)!   -----               |                */
02204         /* | --------   | |  (1 + s^2 K^2) |  * (2n)^(L-n)  */
02205         /* | (n-l-1)!   | |                |                */
02206         /*  -           s=0               -                 */
02207         /****************************************************/
02208 
02209         double ld6 = (ld5+ld4);
02210 
02211         mx d6_mx = mxify_log10( ld6 );
02212         mx dd1_mx = bhG_mx( K, n, l, lp, rcsvV_mxq );
02213         mx dd2_mx = mult_mx( d6_mx, dd1_mx );
02214         normalize_mx( dd2_mx );
02215         double result = unmxify( dd2_mx );
02216 
02217         ASSERT( result != 0. );
02218 
02219         ASSERT( Ksqrd != 0. );
02220         ASSERT( ld3 >= 0. );
02221 
02222         ASSERT( d1 > 0. );
02223         ASSERT( d2 < 0. );
02224         return result;
02225 }
02226 
02227 inline double local_product( double K , long int lp )
02228 {
02229         long int s = 0;
02230 
02231         double Ksqrd =(K*K);
02232         double partprod = 1.;
02233 
02234         for( s = 0; s <= lp; s = s + 1 )
02235         {
02236                 double s2 = (double)(s*s);
02237 
02238                 /**************************/
02239                 /*    s=l'                */
02240                 /*   -----                */
02241                 /*    | |  (1 + s^2 K^2)  */
02242                 /*    | |                 */
02243                 /*    s=0                 */
02244                 /**************************/
02245 
02246                 partprod *= ( 1. + ( s2  * Ksqrd ) );
02247         }
02248         return partprod;
02249 }
02250 
02251 /************************************************************************/
02252 /*  Find the Einstein A's for hydrogen for a                            */
02253 /*  transition n,l -->  n',l'                                           */
02254 /*                                                                      */
02255 /*  In the following, we will assume n > n'                             */
02256 /************************************************************************/
02257 /*******************************************************************************/
02258 /*                                                                             */
02259 /*   Einstein A() for the transition from the                                  */
02260 /*   initial state n,l to the finial state n',l'                               */
02261 /*   is given by oscillator f()                                                */
02262 /*                                                                             */
02263 /*                     hbar w    max(l,l')  |              | 2                 */
02264 /*   f(n,l;n',l') = - -------- ------------ | R(n,l;n',l') |                   */
02265 /*                     3 R_oo   ( 2l + 1 )  |              |                   */
02266 /*                                                                             */
02267 /*                                                                             */
02268 /*                     E(n,l;n',l')     max(l,l')  |              | 2          */
02269 /*   f(n,l;n',l') = -  ------------   ------------ | R(n,l;n',l') |            */
02270 /*                      3 R_oo         ( 2l + 1 )  |              |            */
02271 /*                                                                             */
02272 /*                                                                             */
02273 /*   See for example Gordan Drake's                                            */
02274 /*     Atomic, Molecular, & Optical Physics Handbook pg.638                    */
02275 /*                                                                             */
02276 /*   Here R_oo is the infinite mass Rydberg length                             */
02277 /*                                                                             */
02278 /*                                                                             */
02279 /*        h c                                                                  */
02280 /*   R_oo --- = 13.605698 eV                                                   */
02281 /*        {e}                                                                  */
02282 /*                                                                             */
02283 /*                                                                             */
02284 /*   R_oo =  2.179874e-11 ergs                                                 */
02285 /*                                                                             */
02286 /*   w = omega                                                                 */
02287 /*     = frequency of transition from n,l to n',l'                             */
02288 /*                                                                             */
02289 /*                                                                             */
02290 /*                                                                             */
02291 /*     here g_k are statistical weights obtained from                          */
02292 /*      the appropriate angular momentum quantum numbers                       */
02293 /*                                                                             */
02294 /*                                                                             */
02295 /*                                                          -            -  2  */
02296 /*                   64 pi^4 (e a_o)^2    max(l,l')        |              |    */
02297 /*   A(n,l;n',l') = -------------------  -----------  v^3  | R(n,l;n',l') |    */
02298 /*                         3 h c^3         2*l + 1         |              |    */
02299 /*                                                          -            -     */
02300 /*                                                                             */
02301 /*                                                                             */
02302 /*  pi             3.141592654                                                 */
02303 /*  plank_hbar     6.5821220         eV sec                                    */
02304 /*  R_oo           2.179874e-11      ergs                                      */
02305 /*  plank_h        6.6260755e-34     J sec                                     */
02306 /*  e_charge       1.60217733e-19    C                                         */
02307 /*  a_o            0.529177249e-10   m                                         */
02308 /*  vel_light_c    299792458L        m sec^-1                                  */
02309 /*                                                                             */
02310 /*                                                                             */
02311 /*                                                                             */
02312 /*  64 pi^4 (e a_o)^2    64 pi^4 (a_o)^2    e^2     1                      1   */
02313 /*  ----------------- = ----------------- -------- ----  = 7.5197711e-38 ----- */
02314 /*     3 h c^3                3  c^2       hbar c  2 pi                   sec  */
02315 /*                                                                             */
02316 /*                                                                             */
02317 /*            e^2               1                                              */
02318 /*  using ---------- = alpha = ----                                            */
02319 /*          hbar c             137                                             */
02320 /*******************************************************************************/
02321 
02322 double H_Einstein_A(/*  IN THE FOLLOWING WE HAVE  n > n'                        */
02323         /* principal quantum number, 1 for ground, upper level      */
02324         long int n,
02325         /* angular momentum, 0 for s                                */
02326         long int l,
02327         /* principal quantum number, 1 for ground, lower level      */
02328         long int np,
02329         /* angular momentum, 0 for s                                */
02330         long int lp,
02331         /* Nuclear charge, 1 for H+, 2 for He++, etc                */
02332         long int iz
02333 )
02334 {
02335         DEBUG_ENTRY( "H_Einstein_A()" );
02336 
02337         double result;
02338         if( n > 60 || np > 60 )
02339         {
02340                 result = H_Einstein_A_log10(n,l,np,lp,iz );
02341         }
02342         else
02343         {
02344                 result = H_Einstein_A_lin(n,l,np,lp,iz );
02345         }
02346         return result;
02347 }
02348 
02349 /************************************************************************/
02350 /*   Calculates the Einstein A's for hydrogen                           */
02351 /*   for the transition n,l --> n',l'                                   */
02352 /*   units of sec^(-1)                                                  */
02353 /*                                                                      */
02354 /*  In the following, we have n > n'                                    */
02355 /************************************************************************/
02356 STATIC double H_Einstein_A_lin(/*  IN THE FOLLOWING WE HAVE  n > n'                        */
02357         /* principal quantum number, 1 for ground, upper level      */
02358         long int n,
02359         /* angular momentum, 0 for s                                */
02360         long int l,
02361         /* principal quantum number, 1 for ground, lower level      */
02362         long int np,
02363         /* angular momentum, 0 for s                                */
02364         long int lp,
02365         /* Nuclear charge, 1 for H+, 2 for He++, etc                */
02366         long int iz
02367 )
02368 {
02369         DEBUG_ENTRY( "H_Einstein_A_lin()" );
02370 
02371         /*  hv calculates photon energy in ergs for n -> n' transitions for H and H-like ions */
02372         double d1 = hv( n, np, iz );
02373         double d2 = d1 / HPLANCK; /* v = hv / h */
02374         double d3 = pow3(d2);
02375         double lg = (double)(l > lp ? l : lp);
02376         double Two_L_Plus_One = (double)(2*l + 1);
02377         double d6 = lg / Two_L_Plus_One;
02378         double d7 = hri( n, l, np, lp , iz );
02379         double d8 = d7 * d7;
02380         double result = CONST_ONE * d3 * d6 * d8;
02381 
02382         /* validate the incoming data */
02383         if( n >= 70 )
02384         {
02385                 fprintf(ioQQQ,"Principal Quantum Number `n' too large.\n");
02386                 cdEXIT(EXIT_FAILURE);
02387         }
02388         if( iz < 1 )
02389         {
02390                 fprintf(ioQQQ," The charge is impossible.\n");
02391                 cdEXIT(EXIT_FAILURE);
02392         }
02393         if( n < 1 || np < 1 || l >= n || lp >= np )
02394         {
02395                 fprintf(ioQQQ," The quantum numbers are impossible.\n");
02396                 cdEXIT(EXIT_FAILURE);
02397         }
02398         if( n <= np  )
02399         {
02400                 fprintf(ioQQQ," The principal quantum numbers are such that n <= n'.\n");
02401                 cdEXIT(EXIT_FAILURE);
02402         }
02403         return result;
02404 }
02405 
02406 /**********************log version****************************/
02407 double H_Einstein_A_log10(/* returns Einstein A in units of (sec)^-1                      */
02408         long int n,
02409         long int l,
02410         long int np,
02411         long int lp,
02412         long int iz
02413 )
02414 {
02415         DEBUG_ENTRY( "H_Einstein_A_log10()" );
02416 
02417         /*  hv calculates photon energy in ergs for n -> n' transitions for H and H-like ions */
02418         double d1 = hv( n, np , iz );
02419         double d2 = d1 / HPLANCK; /* v = hv / h */
02420         double d3 = pow3(d2);
02421         double lg = (double)(l > lp ? l : lp);
02422         double Two_L_Plus_One = (double)(2*l + 1);
02423         double d6 = lg / Two_L_Plus_One;
02424         double d7 = hri_log10( n, l, np, lp , iz );
02425         double d8 = d7 * d7;
02426         double result = CONST_ONE * d3 * d6 * d8;
02427 
02428         /* validate the incoming data                         */
02429         if( iz < 1 )
02430         {
02431                 fprintf(ioQQQ," The charge is impossible.\n");
02432                 cdEXIT(EXIT_FAILURE);
02433         }
02434         if( n < 1 || np < 1 || l >= n || lp >= np )
02435         {
02436                 fprintf(ioQQQ," The quantum numbers are impossible.\n");
02437                 cdEXIT(EXIT_FAILURE);
02438         }
02439         if( n <= np  )
02440         {
02441                 fprintf(ioQQQ," The principal quantum numbers are such that n <= n'.\n");
02442                 cdEXIT(EXIT_FAILURE);
02443         }
02444         return result;
02445 }
02446 
02447 /********************************************************************************/
02448 /* hv calculates photon energy for n -> n' transitions for H and H-like ions    */
02449 /*              simplest case of no "l" or "m" dependence                       */
02450 /*  epsilon_0 = 1 in vacu                                                       */
02451 /*                                                                              */
02452 /*                                                                              */
02453 /*                     R_h                                                      */
02454 /*  Energy(n,Z) = -  -------                                                    */
02455 /*                     n^2                                                      */
02456 /*                                                                              */
02457 /*                                                                              */
02458 /*                                                                              */
02459 /*  Friedrich -- Theoretical Atomic Physics  pg. 60   eq. 2.8                   */
02460 /*                                                                              */
02461 /*         u                                                                    */
02462 /*  R_h = --- R_oo  where                                                       */
02463 /*        m_e                                                                   */
02464 /*                                                                              */
02465 /*        h c                                                                   */
02466 /*  R_oo  --- =  2.179874e-11 ergs                                              */
02467 /*         e                                                                    */
02468 /*                                                                              */
02469 /*  (Harmin Lecture Notes for course phy-651 Spring 1994)                       */
02470 /*  where m_e (m_p) is the mass of and electron (proton)                        */
02471 /*  and u is the reduced electron mass for neutral hydrogen                     */
02472 /*                                                                              */
02473 /*                                                                              */
02474 /*         m_e m_p       m_e                                                    */
02475 /*    u = --------- = -----------                                               */
02476 /*        m_e + m_p   1 + m_e/m_p                                               */
02477 /*                                                                              */
02478 /*        m_e                                                                   */
02479 /*  Now  ----- = 0.000544617013                                                 */
02480 /*        m_p                                                                   */
02481 /*            u                                                                 */
02482 /*  so that  --- =  0.999455679                                                 */
02483 /*           m_e                                                                */
02484 /*                                                                              */
02485 /*                                                                              */
02486 /*  returns energy of photon in ergs                                            */
02487 /*                                                                              */
02488 /*  hv (n,n',Z) is for transitions n -> n'                                      */
02489 /*                                                                              */
02490 /*  1 erg = 1e-07 J                                                             */
02491 /********************************************************************************/
02492 /********************************************************************************/
02493 /* WARNING: hv() use the electron reduced mass for hydrogen instead of          */
02494 /*      the reduced mass associated with the apropriate ion                     */
02495 /********************************************************************************/
02496 
02497 inline double hv( long int n, long int nprime, long int iz )
02498 {
02499         DEBUG_ENTRY( "hv()" );
02500 
02501         double n1 = (double)n;
02502         double n2 = n1*n1;
02503         double np1 = (double)nprime;
02504         double np2 = np1*np1;
02505         double rmr = 1./(1. + ELECTRON_MASS/PROTON_MASS); /* 0.999455679 */
02506         double izsqrd = (double)(iz*iz);
02507 
02508         double d1 = 1. / n2;
02509         double d2 = 1. / np2;
02510         double d3 = izsqrd * rmr * EN1RYD;
02511         double d4 = d2 - d1;
02512         double result = d3 * d4;
02513 
02514         ASSERT( n > 0 );
02515         ASSERT( nprime > 0 );
02516         ASSERT( n > nprime );
02517         ASSERT( iz > 0 );
02518         ASSERT( result > 0. );
02519 
02520         if( n <= nprime  )
02521         {
02522                 fprintf(ioQQQ," The principal quantum numbers are such that n <= n'.\n");
02523                 cdEXIT(EXIT_FAILURE);
02524         }
02525 
02526         return result;
02527 }
02528 
02529 /************************************************************************/
02530 /*   hri()                                                              */
02531 /*   Calculate the hydrogen radial wavefunction integral                */
02532 /*   for the dipole transition  l'=l-1  or  l'=l+1                      */
02533 /*   for the higher energy state n,l  to the lower energy state n',l'   */
02534 /*   no "m" dependence                                                  */
02535 /************************************************************************/
02536 /*      here we have a transition                                       */
02537 /*      from the higher energy state n,l                                */
02538 /*      to the lower energy state n',l'                                 */
02539 /*      with a dipole selection rule on l and l'                        */
02540 /************************************************************************/
02541 /*                                                                      */
02542 /*   hri() test n,l,n',l'  for domain errors and                        */
02543 /*              swaps n,l <--> n',l' for the case  l'=l+1               */
02544 /*                                                                      */
02545 /*   It then calls hrii()                                               */
02546 /*                                                                      */
02547 /*   Dec. 6, 1999                                                       */
02548 /*   Robert Paul Bauman                                                 */
02549 /************************************************************************/
02550 
02551 /************************************************************************/
02552 /*      This routine, hri(), calculates the hydrogen radial integral,   */
02553 /*      for the transition n,l --> n',l'                                */
02554 /*      It is, of course, dimensionless.                                */
02555 /*                                                                      */
02556 /*  In the following, we have n > n'                                    */
02557 /************************************************************************/
02558 
02559 inline double hri(
02560         /* principal quantum number, 1 for ground, upper level       */
02561         long int n,
02562         /* angular momentum, 0 for s                                 */
02563         long int l,
02564         /* principal quantum number, 1 for ground, lower level       */
02565         long int np,
02566         /* angular momentum, 0 for s                                 */
02567         long int lp,
02568         /* Nuclear charge, 1 for H+, 2 for He++, etc                 */
02569         long int iz
02570 )
02571 {
02572         DEBUG_ENTRY( "hri" );
02573 
02574         long int a;
02575         long int b;
02576         long int c;
02577         long int d;
02578         double ld1 = 0.;
02579         double Z = (double)iz;
02580 
02581         /**********************************************************************/
02582         /*    from higher energy -> lower energy                              */
02583         /*    Selection Rule for l and l'                                     */
02584         /*    dipole process only                                             */
02585         /**********************************************************************/
02586 
02587         ASSERT( n > 0 );
02588         ASSERT( np > 0 );
02589         ASSERT( l >= 0 );
02590         ASSERT( lp >= 0 );
02591         ASSERT( n > l );
02592         ASSERT( np > lp );
02593         ASSERT( n > np || ( n == np && l == lp + 1 ));
02594         ASSERT( iz > 0 );
02595         ASSERT( lp == l + 1 || lp == l - 1 );
02596 
02597         if( l == lp + 1 )
02598         {
02599                 /*        Keep variable  the same                                 */
02600                 a = n;
02601                 b = l;
02602                 c = np;
02603                 d = lp;
02604         }
02605         else if( l == lp - 1 )
02606         {
02607                 /* swap n,l with n',l'                                            */
02608                 a = np;
02609                 b = lp;
02610                 c = n;
02611                 d = l;
02612         }
02613         else
02614         {
02615                 printf( "BadMagic: l and l' do NOT satisfy dipole requirements.\n\n" );
02616                 cdEXIT(EXIT_FAILURE);
02617         }
02618 
02619         /**********************************************/
02620         /*    Take care of the Z-dependence here.     */
02621         /**********************************************/
02622         ld1 = hrii(a, b, c, d ) / Z;
02623 
02624         return ld1;
02625 }
02626 
02627 /************************************************************************/
02628 /*   hri_log10()                                                        */
02629 /*   Calculate the hydrogen radial wavefunction integral                */
02630 /*   for the dipole transition  l'=l-1  or  l'=l+1                      */
02631 /*   for the higher energy state n,l  to the lower energy state n',l'   */
02632 /*   no "m" dependence                                                  */
02633 /************************************************************************/
02634 /*      here we have a transition                                       */
02635 /*      from the higher energy state n,l                                */
02636 /*      to the lower energy state n',l'                                 */
02637 /*      with a dipole selection rule on l and l'                        */
02638 /************************************************************************/
02639 /*                                                                      */
02640 /*   hri_log10() test n,l,n',l'  for domain errors and                  */
02641 /*              swaps n,l <--> n',l' for the case  l'=l+1               */
02642 /*                                                                      */
02643 /*   It then calls hrii_log()                                           */
02644 /*                                                                      */
02645 /*   Dec. 6, 1999                                                       */
02646 /*   Robert Paul Bauman                                                 */
02647 /************************************************************************/
02648 
02649 inline double hri_log10( long int  n, long int l, long int np, long int lp , long int iz )
02650 {
02651         /**********************************************************************/
02652         /*    from higher energy -> lower energy                              */
02653         /*    Selection Rule for l and l'                                     */
02654         /*    dipole process only                                             */
02655         /**********************************************************************/
02656 
02657         DEBUG_ENTRY( "hri_log10()" );
02658 
02659         long int a;
02660         long int b;
02661         long int c;
02662         long int d;
02663         double ld1 = 0.;
02664         double Z = (double)iz;
02665 
02666         ASSERT( n > 0);
02667         ASSERT( np > 0);
02668         ASSERT( l >= 0);
02669         ASSERT( lp >= 0 );
02670         ASSERT( n > l );
02671         ASSERT( np > lp );
02672         ASSERT( n > np || ( n == np && l == lp + 1 ));
02673         ASSERT( iz > 0 );
02674         ASSERT( lp == l + 1 || lp == l - 1 );
02675 
02676         if( l == lp + 1)
02677         {
02678                 /*        Keep variable  the same                                 */
02679                 a = n;
02680                 b = l;
02681                 c = np;
02682                 d = lp;
02683         }
02684         else if( l == lp - 1 )
02685         {
02686                 /* swap n,l with n',l'                                            */
02687                 a = np;
02688                 b = lp;
02689                 c = n;
02690                 d = l;
02691         }
02692         else
02693         {
02694                 printf( "BadMagic: l and l' do NOT satisfy dipole requirements.\n\n" );
02695                 cdEXIT(EXIT_FAILURE);
02696         }
02697 
02698         /**********************************************/
02699         /*    Take care of the Z-dependence here.     */
02700         /**********************************************/
02701         ld1 = hrii_log(a, b, c, d ) / Z;
02702 
02703         return ld1;
02704 }
02705 
02706 STATIC double hrii( long int n, long int l, long int np, long int lp)
02707 {
02708         /******************************************************************************/
02709         /*      this routine hrii() is internal to the parent routine hri()           */
02710         /*      this internal routine only considers the case l=l'+1                  */
02711         /*      the case l=l-1 is done in the parent routine hri()                    */
02712         /*      by the transformation n <--> n' and l <--> l'                         */
02713         /*      THUS WE TEST FOR                                                      */
02714         /*          l=l'-1                                                            */
02715         /******************************************************************************/
02716 
02717         DEBUG_ENTRY( "hrii()" );
02718 
02719         long int a = 0, b = 0, c = 0;
02720         long int i1 = 0, i2 = 0, i3 = 0, i4 = 0;
02721 
02722         char A='a';
02723 
02724         double y = 0.;
02725         double fsf = 0.;
02726         double d1 = 0., d2 = 0., d3 = 0., d4 = 0., d5 = 0., d6 = 0., d7 = 0.;
02727         double d8 = 0., d9 = 0., d10 = 0., d11 = 0., d12 = 0., d13 = 0., d14 = 0.;
02728         double d00 = 0., d01 = 0.;
02729 
02730         ASSERT( l == lp + 1 );
02731 
02732         if( n == np ) /* SPECIAL CASE 1  */
02733         {
02734                 /**********************************************************/
02735                 /* if lp= l + 1 then it has higher energy                 */
02736                 /* i.e.         no photon                                 */
02737                 /* this is the second time we check this, oh well         */
02738                 /**********************************************************/
02739 
02740                 if( lp != (l - 1) )
02741                 {
02742                         printf( "BadMagic: Energy requirements not met.\n\n" );
02743                         cdEXIT(EXIT_FAILURE);
02744                 }
02745 
02746                 d2 = 3. / 2.;
02747                 i1 = n * n;
02748                 i2 = l * l;
02749                 d5 = (double)(i1 - i2);
02750                 d6 = sqrt(d5);
02751                 d7 = (double)n * d6;
02752                 d8 = d2 * d7;
02753                 return d8;
02754         }
02755         else if( l == np && lp == (l - 1) ) /* A Pair of Easy Special Cases */
02756         {
02757                 if( l == (n - 1) )
02758                 {
02759                         /**********************************************************************/
02760                         /*   R(n,l;n',l') = R(n,n-l;n-1,n-2)                                  */
02761                         /*                                                                    */
02762                         /*                = [(2n-2)(2n-1)]^(1/2)   [4n(n-1)/(2n-1)^2]^n  *    */
02763                         /*                            [(2n-1) - 1/(2n-1)]/4                   */
02764                         /**********************************************************************/
02765 
02766                         d1 = (double)( 2*n - 2 );
02767                         d2 = (double)( 2*n - 1 );
02768                         d3 = d1 * d2;
02769                         d4 = sqrt( d3 );
02770 
02771                         d5 = (double)(4 * n * (n - 1));
02772                         i1 = (2*n - 1);
02773                         d6 = (double)(i1 * i1);
02774                         d7 = d5/ d6;
02775                         d8 = powi( d7, n );
02776 
02777                         d9 = 1./d2;
02778                         d10 = d2 - d9;
02779                         d11 = d10 / 4.;
02780 
02781                         /* Wrap it all up */
02782 
02783                         d12 = d4 * d8 * d11;
02784                         return d12;
02785 
02786                 }
02787                 else
02788                 {
02789                         /******************************************************************************/
02790                         /*   R(n,l;n',l') = R(n,l;l,l-1)                                              */
02791                         /*                                                                            */
02792                         /*                = [(n-l) ... (n+l)/(2l-1)!]^(1/2) [4nl/(n-l)^2]^(l+1) *     */
02793                         /*                            [(n-l)/(n+l)]^(n+l) {1-[(n-l)/(n+l)]^2}/4       */
02794                         /******************************************************************************/
02795 
02796                         d2 = 1.;
02797                         for( i1 = -l; i1 <= l; i1 = i1 + 1 )  /* from n-l to n+l INCLUSIVE */
02798                         {
02799                                 d1 = (double)(n - i1);
02800                                 d2 = d2 * d1;
02801                         }
02802                         i2 = (2*l - 1);
02803                         d3 = factorial( i2 );
02804                         d4 = d2/d3;
02805                         d4 = sqrt( d4 );
02806 
02807 
02808                         d5 = (double)( 4. * n * l );
02809                         i3 = (n - l);
02810                         d6 = (double)( i3 * i3 );
02811                         d7 = d5 / d6;
02812                         d8 = powi( d7, l+1 );
02813 
02814 
02815                         i4 = n + l;
02816                         d9 = (double)( i3 ) / (double)( i4 );
02817                         d10 = powi( d9 , i4 );
02818 
02819                         d11 = d9 * d9;
02820                         d12 = 1. - d11;
02821                         d13 = d12 / 4.;
02822 
02823                         /* Wrap it all up */
02824                         d14 = d4 * d8 * d10 * d13;
02825                         return d14;
02826                 }
02827         }
02828 
02829         /*******************************************************************************************/
02830         /*                                   THE GENERAL CASE                                      */
02831         /*                   USE RECURSION RELATION FOR HYPERGEOMETRIC FUNCTIONS                   */
02832         /*              REF: D. Hoang-Bing Astron. Astrophys. 238: 449-451 (1990)                  */
02833         /*                        For F(a,b;c;x) we have from eq.4                                 */
02834         /*                                                                                         */
02835         /*     (a-c) F(a-1) = a (1-x) [ F(a) - F(a-1) ] + (a + bx - c) F(a)                        */
02836         /*                                                                                         */
02837         /*                     a (1-x)                       (a + bx - c)                          */
02838         /*           F(a-1) = --------- [ F(a) - F(a-1) ] + -------------- F(a)                    */
02839         /*                    (a-c)                            (a-c)                               */
02840         /*                                                                                         */
02841         /*                                                                                         */
02842         /*       A similiar recusion relation holds for b with a <--> b.                           */
02843         /*                                                                                         */
02844         /*                                                                                         */
02845         /*   we have initial conditions                                                            */
02846         /*                                                                                         */
02847         /*                                                                                         */
02848         /*    F(0) = 1              with a = -1                                                    */
02849         /*                                                                                         */
02850         /*                 b                                                                       */
02851         /*   F(-1) = 1 - (---) x    with a = -1                                                    */
02852         /*                 c                                                                       */
02853         /*******************************************************************************************/
02854 
02855         if( lp == l - 1 ) /* use recursion over "b" */
02856         {
02857                 A='b';
02858         }
02859         else if( lp == l + 1 )                 /* use recursion over "a" */
02860         {
02861                 A='a';
02862         }
02863         else
02864         {
02865                 printf(" BadMagic: Don't know what to do here.\n\n");
02866                 cdEXIT(EXIT_FAILURE);
02867         }
02868 
02869         /********************************************************************/
02870         /*   Calculate the whole shootin match                              */
02871         /*                    -                - (1/2)                      */
02872         /*     (-1)^(n'-1)   | (n+l)! (n'+l-1)! |                           */
02873         /*     ----------- * | ---------------- |                           */
02874         /*     [4 (2l-1)!]   | (n-l-1)! (n'-l)! |                           */
02875         /*                    -                -                            */
02876         /*        * (4 n n')^(l+1) (n-n')^(n+n'-2l-2) (n+n')^(-n-n')        */
02877         /*                                                                  */
02878         /*   This is used in the calculation of hydrogen                    */
02879         /*    radial wave function integral for dipole transition case      */
02880         /********************************************************************/
02881 
02882         fsf = fsff( n, l, np );
02883 
02884         /**************************************************************************************/
02885         /*      Use a -> a' + 1                                                               */
02886         /*                                 _                 _                                */
02887         /*              (a' + 1) (1  - x) |                   |                               */
02888         /*      F(a') = ----------------- | F(a'+1) - F(a'+2) | + (a' + 1 + bx -c) F(a'+1)    */
02889         /*                 (a' + 1 -c)    |                   |                               */
02890         /*                                 -                 -                                */
02891         /*                                                                                    */
02892         /*      For the first F() in the solution of the radial integral                      */
02893         /*                                                                                    */
02894         /*            a = ( -n + l + 1 )                                                      */
02895         /*                                                                                    */
02896         /*      a = -n + l + 1                                                                */
02897         /*      max(a)  = max(-n)  + max(l)     + 1                                           */
02898         /*              = -n       + max(n-1)   + 1                                           */
02899         /*              = -n       + n-1        + 1                                           */
02900         /*              = 0                                                                   */
02901         /*                                                                                    */
02902         /*      similiarly                                                                    */
02903         /*                                                                                    */
02904         /*      min(a) = min(-n)   + min(l)   + 1                                             */
02905         /*             = min(-n)   + 0        + 1                                             */
02906         /*             = -n        + 1                                                        */
02907         /*                                                                                    */
02908         /*      a -> a' + 1   implies                                                         */
02909         /*                                                                                    */
02910         /*      max(a') = -1                                                                  */
02911         /*      min(a') = -n                                                                  */
02912         /**************************************************************************************/
02913 
02914         /* a plus                                                     */
02915         a = (-n + l + 1);
02916 
02917         /*  for the first 2_F_1 we use b = (-n' + l)                  */
02918         b = (-np + l);
02919 
02920         /*  c is simple                                               */
02921         c = 2 * l;
02922 
02923         /*             -4 nn'                                         */
02924         /*  where Y = -------- .                                      */
02925         /*            (n-n')^2                                        */
02926         d2 = (double)(n - np);
02927         d3 = d2 * d2;
02928         d4 = 1. / d3;
02929         d5 = (double)(n * np);
02930         d6 = d5 * 4.;
02931         d7 = - d6;
02932         y = d7 * d4;
02933 
02934         d00 = F21( a, b, c, y, A );
02935 
02936         /**************************************************************/
02937         /*  For the second F() in the solution of the radial integral */
02938         /*                                                            */
02939         /*        a = ( -n + l - 1 )                                  */
02940         /*                                                            */
02941         /*  a = -n + l + 1                                            */
02942         /*  max(a) = max(-n) + max(l)   - 1                           */
02943         /*         = -n      + (n - 1)  - 1                           */
02944         /*         = -2                                               */
02945         /*                                                            */
02946         /*  similiarly                                                */
02947         /*                                                            */
02948         /*  min(a) = min(-n) + min(l)   - 1                           */
02949         /*         = (-n)    + 0        - 1                           */
02950         /*         = -n - 1                                           */
02951         /*                                                            */
02952         /*  a -> a' + 1   implies                                     */
02953         /*                                                            */
02954         /*  max(a') = -3                                              */
02955         /*                                                            */
02956         /*  min(a') = -n - 2                                          */
02957         /**************************************************************/
02958 
02959         /*  a minus                                                   */
02960         a = (-n + l - 1);
02961 
02962         /*  for the first 2_F_1 we use b = (-n' + l)                  */
02963         /*    and does not change                                     */
02964         b = (-np + l);
02965 
02966         /* c is simple                                                */
02967         c = 2 * l;
02968 
02969         /**************************************************************/
02970         /*             -4 nn'                                         */
02971         /*  where Y = -------- .                                      */
02972         /*           (n-n')^2                                         */
02973         /**************************************************************/
02974 
02975         /**************************************************************/
02976         /*      These are already calculated a few lines up           */
02977         /*                                                            */
02978         /*      d2 = (double) (n - np);                               */
02979         /*      d3 = d2 * d2;                                         */
02980         /*      d4 = 1/ d3;                                           */
02981         /*      d5 = (double) (n * np);                               */
02982         /*      d6 = d5 * 4.0;                                        */
02983         /*      d7 = - d6;                                            */
02984         /*      y = d7 * d4;                                          */
02985         /**************************************************************/
02986 
02987         d01 = F21(a, b, c, y, A );
02988 
02989         /*  Calculate         */
02990         /*                    */
02991         /*  (n-n')^2          */
02992         /*  --------          */
02993         /*  (n+n')^2          */
02994 
02995         i1 = (n - np);
02996         d1 = pow2( (double)i1 );
02997         i2 = (n + np);
02998         d2 = pow2( (double)i2 );
02999         d3 = d1 / d2;
03000 
03001         d4 = d01 * d3;
03002         d5 = d00 - d4;
03003         d6 = fsf * d5;
03004 
03005         ASSERT( d6 != 0. );
03006         return d6;
03007 }
03008 
03009 
03010 STATIC double hrii_log( long int  n, long int  l, long int np, long int lp)
03011 {
03012         /******************************************************************************/
03013         /*      this routine hrii_log() is internal to the parent routine hri_log10() */
03014         /*      this internal routine only considers the case l=l'+1                  */
03015         /*      the case l=l-1 is done in the parent routine hri_log10()              */
03016         /*      by the transformation n <--> n' and l <--> l'                         */
03017         /*      THUS WE TEST FOR                                                      */
03018         /*          l=l'-1                                                            */
03019         /******************************************************************************/
03020         /**************************************************************************************/
03021         /*   THIS HAS THE GENERAL FORM GIVEN BY (GORDAN 1929):                                */
03022         /*                                                                                    */
03023         /*    R(n,l;n',l') = (-1)^(n'-1) [4(2l-1)!]^(-1) *                                    */
03024         /*                      [(n+l)! (n'+l-1)!/(n-l-1)! (n'-l)!]^(1/2) *                   */
03025         /*                      (4 n n')^(l+1) (n-n')^(n+n'-2l-2) (n+n')^(-n-n') *            */
03026         /*                      { F(-n+l+1,-n'+l;2l;-4nn'/[n-n']^2)                           */
03027         /*                    - (n-n')^2 (n+n')^2 F(-n+l-1,-n'+l;2l; -4nn'/[n-n']^2 ) }       */
03028         /**************************************************************************************/
03029 
03030         DEBUG_ENTRY( "hrii_log()" );
03031 
03032         char A='a';
03033 
03034         double y = 0.;
03035         double log10_fsf = 0.;
03036 
03037         ASSERT( l == lp + 1 );
03038 
03039         if( n == np ) /* SPECIAL CASE 1                              */
03040         {
03041                 /**********************************************************/
03042                 /* if lp= l + 1 then it has higher energy                 */
03043                 /* i.e.         no photon                                 */
03044                 /* this is the second time we check this, oh well         */
03045                 /**********************************************************/
03046 
03047                 if( lp != (l - 1) )
03048                 {
03049                         printf( "BadMagic: l'= l+1 for n'= n.\n\n" );
03050                         cdEXIT(EXIT_FAILURE);
03051                 }
03052                 else
03053                 {
03054                         /**********************************************************/
03055                         /*                        3                               */
03056                         /*   R(nl:n'=n,l'=l+1) = ---  n  sqrt( n^2 - l^2 )        */
03057                         /*                        2                               */
03058                         /**********************************************************/
03059 
03060                         long int i1 = n * n;
03061                         long int i2 = l * l;
03062 
03063                         double d1 = 3. / 2.;
03064                         double d2 = (double)n;
03065                         double d3 = (double)(i1 - i2);
03066                         double d4 = sqrt(d3);
03067                         double result = d1 * d2 * d4;
03068 
03069                         ASSERT( d3 >= 0. );
03070                         return result;
03071                 }
03072         }
03073         else if( l == np && lp == l - 1 ) /* A Pair of Easy Special Cases          */
03074         {
03075                 if( l == n - 1 )
03076                 {
03077                         /**********************************************************************/
03078                         /*   R(n,l;n',l') = R(n,n-l;n-1,n-2)                                  */
03079                         /*                                                                    */
03080                         /*                = [(2n-2)(2n-1)]^(1/2)   [4n(n-1)/(2n-1)^2]^n  *    */
03081                         /*                            [(2n-1) - 1/(2n-1)]/4                   */
03082                         /**********************************************************************/
03083 
03084                         double d1 = (double)((2*n-2)*(2*n-1));
03085                         double d2 = sqrt( d1 );
03086                         double d3 = (double)(4*n*(n-1));
03087                         double d4 = (double)(2*n-1);
03088                         double d5 = d4*d4;
03089                         double d7 = d3/d5;
03090                         double d8 = powi(d7,n);
03091                         double d9 = 1./d4;
03092                         double d10 = d4 - d9;
03093                         double d11 = 0.25*d10;
03094                         double result = (d2 * d8 * d11); /* Wrap it all up */
03095 
03096                         ASSERT( d1 >= 0. );
03097                         ASSERT( d3 >= 0. );
03098                         return result;
03099                 }
03100                 else
03101                 {
03102                         double result = 0.;
03103                         double ld1 = 0., ld2 = 0., ld3 = 0., ld4 = 0., ld5 = 0., ld6 = 0., ld7 = 0.;
03104 
03105                         /******************************************************************************/
03106                         /*   R(n,l;n',l') = R(n,l;l,l-1)                                              */
03107                         /*                                                                            */
03108                         /*                = [(n-l) ... (n+l)/(2l-1)!]^(1/2) [4nl/(n-l)^2]^(l+1) *     */
03109                         /*                            [(n-l)/(n+l)]^(n+l) {1-[(n-l)/(n+l)]^2}/4       */
03110                         /******************************************************************************/
03111                         /**************************************/
03112                         /*    [(n-l) ... (n+l)]               */
03113                         /**************************************/
03114                         /*    log10[(n-l) ... (n+l)] =        */
03115                         /*                                    */
03116                         /*        n+l                         */
03117                         /*        ---                         */
03118                         /*         >  log10(j)                */
03119                         /*        ---                         */
03120                         /*      j=n-l                         */
03121                         /**************************************/
03122 
03123                         ld1 = 0.;
03124                         for( long int i1 = (n-l); i1 <= (n+l); i1++ )  /* from n-l to n+l INCLUSIVE           */
03125                         {
03126                                 double d1 = (double)(i1);
03127                                 ld1 += log10( d1 );
03128                         }
03129 
03130                         /**************************************/
03131                         /*    (2l-1)!                         */
03132                         /**************************************/
03133                         /*    log10[ (2n-1)! ]                */
03134                         /**************************************/
03135 
03136                         ld2 = lfactorial( 2*l - 1 );
03137 
03138                         ASSERT( ((2*l)+1) >= 0);
03139 
03140                         /**********************************************/
03141                         /* log10( [(n-l) ... (n+l)/(2l-1)!]^(1/2) ) = */
03142                         /*    (1/2) log10[(n-l) ... (n+l)] -          */
03143                         /*            (1/2) log10[ (2n-1)! ]          */
03144                         /**********************************************/
03145 
03146                         ld3 = 0.5 * (ld1 - ld2);
03147 
03148                         /**********************************************/
03149                         /*            [4nl/(n-l)^2]^(l+1)             */
03150                         /**********************************************/
03151                         /*  log10( [4nl/(n-l)^2]^(l+1) ) =            */
03152                         /*       (l+1) * log10( [4nl/(n-l)^2] )       */
03153                         /*                                            */
03154                         /*    = (l+1)*[ log10(4nl) - 2 log10(n-l) ]   */
03155                         /*                                            */
03156                         /**********************************************/
03157 
03158                         double d1 = (double)(l+1);
03159                         double d2 = (double)(4*n*l);
03160                         double d3 = (double)(n-l);
03161                         double d4 = log10(d2);
03162                         double d5 = log10(d3);
03163 
03164                         ld4 = d1 * (d4 - 2.*d5);
03165 
03166                         /**********************************************/
03167                         /*             [(n-l)/(n+l)]^(n+l)            */
03168                         /**********************************************/
03169                         /*   log10( [ (n-l)/(n+l) ]^(n+l)  ) =        */
03170                         /*                                            */
03171                         /*    (n+l) * [ log10(n-l) - log10(n+l) ]     */
03172                         /*                                            */
03173                         /**********************************************/
03174 
03175                         d1 = (double)(n-l);
03176                         d2 = (double)(n+l);
03177                         d3 = log10( d1 );
03178                         d4 = log10( d2 );
03179 
03180                         ld5 = d2 * (d3 - d4);
03181 
03182                         /**********************************************/
03183                         /*      {1-[(n-l)/(n+l)]^2}/4                 */
03184                         /**********************************************/
03185                         /*   log10[ {1-[(n-l)/(n+l)]^2}/4 ]           */
03186                         /**********************************************/
03187 
03188                         d1 = (double)(n-l);
03189                         d2 = (double)(n+l);
03190                         d3 = d1/d2;
03191                         d4 = d3*d3;
03192                         d5 = 1. - d4;
03193                         double d6 = 0.25*d5;
03194 
03195                         ld6 = log10(d6);
03196 
03197                         /******************************************************************************/
03198                         /*   R(n,l;n',l') = R(n,l;l,l-1)                                              */
03199                         /*                                                                            */
03200                         /*                = [(n-l) ... (n+l)/(2l-1)!]^(1/2) [4nl/(n-l)^2]^(l+1) *     */
03201                         /*                            [(n-l)/(n+l)]^(n+l) {1-[(n-l)/(n+l)]^2}/4       */
03202                         /******************************************************************************/
03203 
03204                         ld7 = ld3 + ld4 + ld5 + ld6;
03205 
03206                         result = pow( 10., ld7 );
03207 
03208                         ASSERT( result > 0. );
03209                         return result;
03210                 }
03211         }
03212         else
03213         {
03214                 double result = 0.;
03215                 long int a = 0, b = 0, c = 0;
03216                 double d1 = 0., d2 = 0., d3 = 0., d4 = 0., d5 = 0., d6 = 0., d7 = 0.;
03217                 mx d00={0.0,0}, d01={0.0,0}, d02={0.0,0}, d03={0.0,0};
03218 
03219                 if( lp == l - 1 ) /* use recursion over "b"  */
03220                 {
03221                         A='b';
03222                 }
03223                 else if( lp == l + 1 )               /* use recursion over "a"  */
03224                 {
03225                         A='a';
03226                 }
03227                 else
03228                 {
03229                         printf(" BadMagic: Don't know what to do here.\n\n");
03230                         cdEXIT(EXIT_FAILURE);
03231                 }
03232 
03233                 /**************************************************************************************/
03234                 /*   THIS HAS THE GENERAL FORM GIVEN BY (GORDAN 1929):                                */
03235                 /*                                                                                    */
03236                 /*    R(n,l;n',l') = (-1)^(n'-1) [4(2l-1)!]^(-1) *                                    */
03237                 /*                      [(n+l)! (n'+l-1)!/(n-l-1)! (n'-l)!]^(1/2) *                   */
03238                 /*                      (4 n n')^(l+1) (n-n')^(n+n'-2l-2) (n+n')^(-n-n') *            */
03239                 /*                      { F(-n+l+1,-n'+l;2l;-4nn'/[n-n']^2)                           */
03240                 /*                    - (n-n')^2 (n+n')^2 F(-n+l-1,-n'+l;2l; -4nn'/[n-n']^2 ) }       */
03241                 /**************************************************************************************/
03242 
03243                 /****************************************************************************************************/
03244                 /* Calculate the whole shootin match                                                                */
03245                 /*                            -                - (1/2)                                              */
03246                 /*             (-1)^(n'-1)   | (n+l)! (n'+l-1)! |                                                   */
03247                 /*  fsff() =   ----------- * | ---------------- | * (4 n n')^(l+1) (n-n')^(n+n'-2l-2)(n+n')^(-n-n') */
03248                 /*             [4 (2l-1)!]   | (n-l-1)! (n'-l)! |                                                   */
03249                 /*                            -                -                                                    */
03250                 /* This is used in the calculation of hydrogen radial wave function integral for dipole transitions */
03251                 /****************************************************************************************************/
03252 
03253                 log10_fsf = log10_fsff( n, l, np );
03254 
03255                 /******************************************************************************************/
03256                 /*  2_F_1( a, b; c; y )                                                                   */
03257                 /*                                                                                        */
03258                 /*        F21_mx(-n+l+1, -n'+l; 2l; -4nn'/[n-n']^2)                                       */
03259                 /*                                                                                        */
03260                 /*                                                                                        */
03261                 /*      Use a -> a' + 1                                                                   */
03262                 /*                                 _                 _                                    */
03263                 /*              (a' + 1) (1 - x)  |                   |                                   */
03264                 /*      F(a') = ----------------- | F(a'+1) - F(a'+2) | + (a' + 1 + bx -c) F(a'+1)        */
03265                 /*                 (a' + 1 - c)   |                   |                                   */
03266                 /*                                 -                 -                                    */
03267                 /*                                                                                        */
03268                 /*      For the first F() in the solution of the radial integral                          */
03269                 /*                                                                                        */
03270                 /*            a = ( -n + l + 1 )                                                          */
03271                 /*                                                                                        */
03272                 /*      a = -n + l + 1                                                                    */
03273                 /*      max(a)  = max(-n)  + max(l)     + 1                                               */
03274                 /*              = -n       + max(n-1)   + 1                                               */
03275                 /*              = -n       + n-1        + 1                                               */
03276                 /*              = 0                                                                       */
03277                 /*                                                                                        */
03278                 /*      similiarly                                                                        */
03279                 /*                                                                                        */
03280                 /*      min(a) = min(-n)   + min(l)   + 1                                                 */
03281                 /*             = min(-n)   + 0        + 1                                                 */
03282                 /*             = -n        + 1                                                            */
03283                 /*                                                                                        */
03284                 /*      a -> a' + 1   implies                                                             */
03285                 /*                                                                                        */
03286                 /*      max(a') = -1                                                                      */
03287                 /*      min(a') = -n                                                                      */
03288                 /******************************************************************************************/
03289 
03290                 /* a plus                                                                         */
03291                 a = (-n + l + 1);
03292 
03293                 /*  for the first 2_F_1 we use b = (-n' + l)                                      */
03294                 b = (-np + l);
03295 
03296                 /*  c is simple                                                                   */
03297                 c = 2 * l;
03298 
03299                 /**********************************************************************************/
03300                 /*  2_F_1( a, b; c; y )                                                           */
03301                 /*                                                                                */
03302                 /*        F21_mx(-n+l+1, -n'+l; 2l; -4nn'/[n-n']^2)                               */
03303                 /*                                                                                */
03304                 /*             -4 nn'                                                             */
03305                 /*  where Y = -------- .                                                          */
03306                 /*            (n-n')^2                                                            */
03307                 /*                                                                                */
03308                 /**********************************************************************************/
03309 
03310                 d2 = (double)(n - np);
03311                 d3 = d2 * d2;
03312 
03313                 d4 = 1. / d3;
03314                 d5 = (double)(n * np);
03315                 d6 = d5 * 4.;
03316 
03317                 d7 = -d6;
03318                 y = d7 * d4;
03319 
03320                 /**************************************************************************************************/
03321                 /*                                   THE GENERAL CASE                                             */
03322                 /*                   USE RECURSION RELATION FOR HYPERGEOMETRIC FUNCTIONS                          */
03323                 /*     for F(a,b;c;x) we have from eq.4   D. Hoang-Bing Astron. Astrophys. 238: 449-451 (1990)    */
03324                 /*                                                                                                */
03325                 /*     (a-c) F(a-1) = a (1-x) [ F(a) - F(a-1) ] + (a + bx - c) F(a)                               */
03326                 /*                                                                                                */
03327                 /*                     a (1-x)                       (a + bx - c)                                 */
03328                 /*           F(a-1) = --------- [ F(a) - F(a-1) ] + -------------- F(a)                           */
03329                 /*                     (a - c)                          (a - c)                                   */
03330                 /*                                                                                                */
03331                 /*                                                                                                */
03332                 /*       A similiar recusion relation holds for b with a <--> b.                                  */
03333                 /*                                                                                                */
03334                 /*                                                                                                */
03335                 /*   we have initial conditions                                                                   */
03336                 /*                                                                                                */
03337                 /*                                                                                                */
03338                 /*    F(0) = 1              with a = -1                                                           */
03339                 /*                                                                                                */
03340                 /*                 b                                                                              */
03341                 /*   F(-1) = 1 - (---) x    with a = -1                                                           */
03342                 /*                 c                                                                              */
03343                 /**************************************************************************************************/
03344 
03345                 /*  2_F_1( long int a, long int b, long int c, (double) y, (string) "a" or "b")   */
03346                 /*        F(-n+l+1,-n'+l;2l;-4nn'/[n-n']^2)                                       */
03347                 d00 = F21_mx( a, b, c, y, A );
03348 
03349                 /**************************************************************/
03350                 /*  For the second F() in the solution of the radial integral */
03351                 /*                                                            */
03352                 /*        a = ( -n + l - 1 )                                  */
03353                 /*                                                            */
03354                 /*  a = -n + l + 1                                            */
03355                 /*  max(a) = max(-n) + max(l)   - 1                           */
03356                 /*         = -n      + (n - 1)  - 1                           */
03357                 /*         = -2                                               */
03358                 /*                                                            */
03359                 /*  similiarly                                                */
03360                 /*                                                            */
03361                 /*  min(a) = min(-n) + min(l)   - 1                           */
03362                 /*         = (-n)    + 0        - 1                           */
03363                 /*         = -n - 1                                           */
03364                 /*                                                            */
03365                 /*  a -> a' + 1   implies                                     */
03366                 /*                                                            */
03367                 /*  max(a') = -3                                              */
03368                 /*                                                            */
03369                 /*  min(a') = -n - 2                                          */
03370                 /**************************************************************/
03371 
03372                 /*  a minus                                       */
03373                 a = (-n + l - 1);
03374 
03375                 /*  for the first 2_F_1 we use b = (-n' + l)      */
03376                 /*    and does not change                         */
03377                 b = (-np + l);
03378 
03379                 /* c is simple                                    */
03380                 c = 2 * l;
03381 
03382                 /**************************************************************/
03383                 /*             -4 nn'                                         */
03384                 /*  where Y = -------- .                                      */
03385                 /*           (n-n')^2                                         */
03386                 /**************************************************************/
03387 
03388                 /**************************************************************/
03389                 /*      These are already calculated a few lines up           */
03390                 /*                                                            */
03391                 /*      d2 = (double) (n - np);                               */
03392                 /*      d3 = d2 * d2;                                         */
03393                 /*      d4 = 1/ d3;                                           */
03394                 /*      d5 = (double) (n * np);                               */
03395                 /*      d6 = d5 * 4.0;                                        */
03396                 /*      d7 = - d6;                                            */
03397                 /*      y = d7 * d4;                                          */
03398                 /**************************************************************/
03399 
03400                 d01 = F21_mx(a, b, c, y, A );
03401 
03402                 /**************************************************************************************/
03403                 /*   THIS HAS THE GENERAL FORM GIVEN BY (GORDAN 1929):                                */
03404                 /*                                                                                    */
03405                 /*    R(n,l;n',l') = (-1)^(n'-1) [4(2l-1)!]^(-1) *                                    */
03406                 /*                      [(n+l)! (n'+l-1)!/(n-l-1)! (n'-l)!]^(1/2) *                   */
03407                 /*                      (4 n n')^(l+1) (n-n')^(n+n'-2l-2) (n+n')^(-n-n') *            */
03408                 /*                      { F(-n+l+1,-n'+l;2l;-4nn'/[n-n']^2)                           */
03409                 /*                    - (n-n')^2 (n+n')^2 F(-n+l-1,-n'+l;2l; -4nn'/[n-n']^2 ) }       */
03410                 /*                                                                                    */
03411                 /*                = fsf * ( F(a,b,c;y)  - d3 * F(a',b',c';y) )                        */
03412                 /*                                                                                    */
03413                 /*        where d3 = (n-n')^2 (n+n')^2                                                */
03414                 /*                                                                                    */
03415                 /**************************************************************************************/
03416 
03417                 /**************************************************************/
03418                 /*  Calculate                                                 */
03419                 /*                                                            */
03420                 /*  (n-n')^2                                                  */
03421                 /*  --------                                                  */
03422                 /*  (n+n')^2                                                  */
03423                 /**************************************************************/
03424 
03425                 d1 = (double)((n - np)*(n -np));
03426                 d2 = (double)((n + np)*(n + np));
03427                 d3 = d1 / d2;
03428 
03429                 d02.x = d01.x;
03430                 d02.m = d01.m * d3;
03431 
03432                 while ( fabs(d02.m) > 1.0e+25 )
03433                 {
03434                         d02.m /= 1.0e+25;
03435                         d02.x += 25;
03436                 }
03437 
03438                 d03.x = d00.x;
03439                 d03.m = d00.m * (1. - (d02.m/d00.m) * powi( 10. , (d02.x - d00.x) ) );
03440 
03441                 result = pow( 10., (log10_fsf + d03.x) ) * d03.m;
03442 
03443                 ASSERT( result != 0. );
03444 
03445                 /* we don't care about the correct sign of result... */
03446                 return fabs(result);
03447         }
03448 }
03449 
03450 STATIC double fsff( long int n, long int l, long int np )
03451 {
03452         /****************************************************************/
03453         /*   Calculate the whole shootin match                          */
03454         /*                    -                - (1/2)                  */
03455         /*     (-1)^(n'-1)   | (n+l)! (n'+l-1)! |                       */
03456         /*     ----------- * | ---------------- |                       */
03457         /*     [4 (2l-1)!]   | (n-l-1)! (n'-l)! |                       */
03458         /*                    -                -                        */
03459         /*         * (4 n n')^(l+1) (n-n')^(n+n'-2l-2) (n+n')^(-n-n')   */
03460         /*                                                              */
03461         /****************************************************************/
03462 
03463         DEBUG_ENTRY( "fsff()" );
03464 
03465         long int i0 = 0, i1 = 0, i2 = 0, i3 = 0, i4 = 0;
03466         double d0 = 0., d1 = 0., d2 = 0., d3 = 0., d4 = 0., d5 = 0.;
03467         double sigma = 1.;
03468 
03469         /****************************************************************
03470          *   Calculate the whole shootin match                          *        
03471          *     (-1)^(n'-1)   | (n+l)! (n'+l-1)! |                       *
03472          *     ----------- * | ---------------- |                       *
03473          *     [4 (2l-1)!]   | (n-l-1)! (n'-l)! |                       *
03474          *                    -                -                        *
03475          *         * (4 n n')^(l+1) (n-n')^(n+n'-2l-2) (n+n')^(-n-n')   *
03476          *                                                              *
03477          ****************************************************************/
03478 
03479         /* Calculate (-1)^(n'-l) */
03480         if( is_odd(np - l) )
03481         {
03482                 sigma *= -1.;
03483         }
03484         ASSERT( sigma != 0. );
03485 
03486         /*********************/
03487         /* Calculate (2l-1)! */
03488         /*********************/
03489         i1 = (2*l - 1);
03490         if( i1 < 0 )
03491         {
03492                 printf( "BadMagic: Relational error amongst n, l, n' and l'\n" );
03493                 cdEXIT(EXIT_FAILURE);
03494         }
03495 
03496         /****************************************************************/
03497         /*   Calculate the whole shootin match                          */
03498         /*                    -                - (1/2)                  */
03499         /*     (-1)^(n'-1)   | (n+l)! (n'+l-1)! |                       */
03500         /*     ----------- * | ---------------- |                       */
03501         /*     [4 (2l-1)!]   | (n-l-1)! (n'-l)! |                       */
03502         /*                    -                -                        */
03503         /*         * (4 n n')^(l+1) (n-n')^(n+n'-2l-2) (n+n')^(-n-n')   */
03504         /*                                                              */
03505         /****************************************************************/
03506 
03507         d0 = factorial( i1 );
03508         d1 = 4. * d0;
03509         d2 = 1. / d1;
03510 
03511         /**********************************************************************/
03512         /*    We want the (negitive) of this                                  */
03513         /*    since we really are interested in                               */
03514         /*    [(2l-1)!]^-1                                                    */
03515         /**********************************************************************/
03516 
03517         sigma = sigma * d2;
03518         ASSERT( sigma != 0. );
03519 
03520         /**********************************************************************/
03521         /* Calculate (4 n n')^(l+1)                                           */
03522         /* powi( m , n) calcs m^n                                             */
03523         /* returns long double with m,n ints                                  */
03524         /**********************************************************************/
03525 
03526         i0 = 4 * n * np;
03527         i1 = l + 1;
03528         d2 = powi( (double)i0 , i1 );
03529         sigma = sigma * d2;
03530         ASSERT( sigma != 0. );
03531 
03532         /* Calculate (n-n')^(n+n'-2l-2)                                       */
03533         i0 = n - np;
03534         i1 = n + np - 2*l - 2;
03535         d2 = powi( (double)i0 , i1 );
03536         sigma = sigma * d2;
03537         ASSERT( sigma != 0. );
03538 
03539         /* Calculate (n+n')^(-n-n')                                           */
03540         i0 = n + np;
03541         i1 = -n - np;
03542         d2 = powi( (double)i0 , i1 );
03543         sigma = sigma * d2;
03544         ASSERT( sigma != 0. );
03545 
03546         /**********************************************************************/
03547         /*                  -                -  (1/2)                         */
03548         /*                 | (n+l)! (n'+l-1)! |                               */
03549         /*     Calculate   | ---------------- |                               */
03550         /*                 | (n-l-1)! (n'-l)! |                               */
03551         /*                  -                -                                */
03552         /**********************************************************************/
03553 
03554         i1 = n + l;
03555         if( i1 < 0 )
03556         {
03557                 printf( "BadMagic: Relational error amongst n, l, n' and l'\n" );
03558                 cdEXIT(EXIT_FAILURE);
03559         }
03560         d1 = factorial( i1 );
03561 
03562         i2 = np + l - 1;
03563         if( i2 < 0 )
03564         {
03565                 printf( "BadMagic: Relational error amongst n, l, n' and l'\n" );
03566                 cdEXIT(EXIT_FAILURE);
03567         }
03568         d2 = factorial( i2 );
03569 
03570         i3 = n - l - 1;
03571         if( i3 < 0 )
03572         {
03573                 printf( "BadMagic: Relational error amongst n, l, n' and l'\n" );
03574                 cdEXIT(EXIT_FAILURE);
03575         }
03576         d3 = factorial( i3 );
03577 
03578         i4 = np - l;
03579         if( i4 < 0 )
03580         {
03581                 printf( "BadMagic: Relational error amongst n, l, n' and l'\n" );
03582                 cdEXIT(EXIT_FAILURE);
03583         }
03584         d4 = factorial( i4 );
03585 
03586         ASSERT( d3 != 0. );
03587         ASSERT( d4 != 0. );
03588 
03589         /* Do this a different way to prevent overflow */
03590         /* d5 = (sqrt(d1 *d2)); */
03591         d5 = sqrt(d1)*sqrt(d2);
03592         d5 /= sqrt(d3);
03593         d5 /= sqrt(d4);
03594 
03595         sigma = sigma * d5;
03596 
03597         ASSERT( sigma != 0. );
03598         return sigma;
03599 }
03600 
03601 /**************************log version*******************************/
03602 STATIC double log10_fsff( long int n, long int l, long int np )
03603 {
03604         /******************************************************************************************************/
03605         /*   Calculate the whole shootin match                                                                */
03606         /*                    -                - (1/2)                                                        */
03607         /*         1         | (n+l)! (n'+l-1)! |                                                             */
03608         /*     ----------- * | ---------------- |      * (4 n n')^(l+1) (n-n')^(n+n'-2l-2) (n+n')^(-n-n')     */
03609         /*     [4 (2l-1)!]   | (n-l-1)! (n'-l)! |                                                             */
03610         /*                    -                -                                                              */
03611         /******************************************************************************************************/
03612 
03613         DEBUG_ENTRY( "log10_fsff()" );
03614 
03615         double d0 = 0., d1 = 0.;
03616         double ld0 = 0., ld1 = 0., ld2 = 0., ld3 = 0., ld4 = 0.;
03617         double result = 0.;
03618 
03619         /******************************************************************************************************/
03620         /*    Calculate the log10 of the whole shootin match                                                  */
03621         /*                    -                - (1/2)                                                        */
03622         /*          1        | (n+l)! (n'+l-1)! |                                                             */
03623         /*     ----------- * | ---------------- |      * (4 n n')^(l+1) (n-n')^(n+n'-2l-2) (n+n')^(-n-n')     */
03624         /*     [4 (2l-1)!]   | (n-l-1)! (n'-l)! |                                                             */
03625         /*                    -                -                                                              */
03626         /******************************************************************************************************/
03627 
03628         /**********************/
03629         /* Calculate (2l-1)!  */
03630         /**********************/
03631 
03632         d0 = (double)(2*l - 1);
03633         ASSERT( d0 != 0. );
03634 
03635         /******************************************************************************************************/
03636         /*    Calculate the whole shootin match                                                               */
03637         /*                    -                - (1/2)                                                        */
03638         /*         1         | (n+l)! (n'+l-1)! |                                                             */
03639         /*     ----------- * | ---------------- |      * (4 n n')^(l+1) |(n-n')^(n+n'-2l-2)| (n+n')^(-n-n')   */
03640         /*     [4 (2l-1)!]   | (n-l-1)! (n'-l)! |                                                             */
03641         /*                    -                -                                                              */
03642         /******************************************************************************************************/
03643 
03644         ld0 = lfactorial( 2*l - 1 );
03645         ld1 = log10(4.);
03646         result = -(ld0 + ld1);
03647         ASSERT( result != 0. );
03648 
03649         /**********************************************************************/
03650         /* Calculate (4 n n')^(l+1)                                           */
03651         /* powi( m , n) calcs m^n                                             */
03652         /* returns long double with m,n ints                                  */
03653         /**********************************************************************/
03654 
03655         d0 = (double)(4 * n * np);
03656         d1 = (double)(l + 1);
03657         result  += d1 * log10(d0);
03658         ASSERT( d0 >= 0. );
03659         ASSERT( d1 != 0. );
03660 
03661         /**********************************************************************/
03662         /* Calculate |(n-n')^(n+n'-2l-2)|                                     */
03663         /*    NOTE: Here we are interested only                               */
03664         /*             magnitude of (n-n')^(n+n'-2l-2)                        */
03665         /**********************************************************************/
03666 
03667         d0 = (double)(n - np);
03668         d1 = (double)(n + np - 2*l - 2);
03669         result  += d1 * log10(fabs(d0));
03670         ASSERT( fabs(d0) > 0. );
03671         ASSERT( d1 != 0. );
03672 
03673         /* Calculate (n+n')^(-n-n') */
03674         d0 = (double)(n + np);
03675         d1 = (double)(-n - np);
03676         result += d1 * log10(d0);
03677         ASSERT( d0 > 0. );
03678         ASSERT( d1 != 0. );
03679 
03680         /**********************************************************************/
03681         /*                  -                -  (1/2)                         */
03682         /*                 | (n+l)! (n'+l-1)! |                               */
03683         /*     Calculate   | ---------------- |                               */
03684         /*                 | (n-l-1)! (n'-l)! |                               */
03685         /*                  -                -                                */
03686         /**********************************************************************/
03687 
03688         ASSERT( n+l > 0 );
03689         ld0 = lfactorial( n + l );
03690 
03691         ASSERT( np+l-1 > 0 );
03692         ld1 = lfactorial( np + l - 1 );
03693 
03694         ASSERT( n-l-1 >= 0 );
03695         ld2 = lfactorial( n - l - 1 );
03696 
03697         ASSERT( np-l >= 0 );
03698         ld3 = lfactorial( np - l );
03699 
03700         ld4 = 0.5*((ld0+ld1)-(ld2+ld3));
03701 
03702         result += ld4;
03703         ASSERT( result != 0. );
03704         return result;
03705 }
03706 
03707 /***************************************************************************/
03708 /*   Find the Oscillator Strength for hydrogen for any                     */
03709 /*   transition n,l -->  n',l'                                             */
03710 /*   returns a double                                                      */
03711 /***************************************************************************/
03712 
03713 /************************************************************************/
03714 /*   Find the Oscillator Strength for hydrogen for any                  */
03715 /*   transition n,l -->  n',l'                                          */
03716 /*   returns a double                                                   */
03717 /*                                                                      */
03718 /*   Einstein A() for the transition from the                           */
03719 /*   initial state n,l to the finial state n',l'                        */
03720 /*   require  the  Oscillator Strength  f()                             */
03721 /*                                                                      */
03722 /*                     hbar w    max(l,l')  |              | 2          */
03723 /*   f(n,l;n',l') = - -------- ------------ | R(n,l;n',l') |            */
03724 /*                     3 R_oo   ( 2l + 1 )  |              |            */
03725 /*                                                                      */
03726 /*                                                                      */
03727 /*                                                                      */
03728 /*                     E(n,l;n',l')     max(l,l')  |              | 2   */
03729 /*   f(n,l;n',l') = -  ------------   ------------ | R(n,l;n',l') |     */
03730 /*                      3 R_oo         ( 2l + 1 )  |              |     */
03731 /*                                                                      */
03732 /*                                                                      */
03733 /*   See for example Gordan Drake's                                     */
03734 /*      Atomic, Molecular, & Optical Physics Handbook pg.638            */
03735 /*                                                                      */
03736 /*   Here R_oo is the infinite mass Rydberg length                      */
03737 /*                                                                      */
03738 /*                                                                      */
03739 /*        h c                                                           */
03740 /*   R_oo --- = 13.605698 eV                                            */
03741 /*        {e}                                                           */
03742 /*                                                                      */
03743 /*                                                                      */
03744 /*   R_oo =  2.179874e-11 ergs                                          */
03745 /*                                                                      */
03746 /*   w = omega                                                          */
03747 /*     = frequency of transition from n,l to n',l'                      */
03748 /*                                                                      */
03749 /*                                                                      */
03750 /*                                                                      */
03751 /*     here g_k are statistical weights obtained from                   */
03752 /*              the appropriate angular momentum quantum numbers        */
03753 /************************************************************************/
03754 
03755 /********************************************************************************/
03756 /*   Calc the Oscillator Strength f(*) given by                                 */
03757 /*                                                                              */
03758 /*                     E(n,l;n',l')     max(l,l')  |              | 2           */
03759 /*   f(n,l;n',l') = -  ------------   ------------ | R(n,l;n',l') |             */
03760 /*                      3 R_oo         ( 2l + 1 )  |              |             */
03761 /*                                                                              */
03762 /*   See for example Gordan Drake's                                             */
03763 /*      Atomic, Molecular, & Optical Physics Handbook pg.638                    */
03764 /********************************************************************************/
03765 
03766 /************************************************************************/
03767 /*   Calc the Oscillator Strength f(*) given by                         */
03768 /*                                                                      */
03769 /*                     E(n,l;n',l')     max(l,l')  |              | 2   */
03770 /*   f(n,l;n',l') = -  ------------   ------------ | R(n,l;n',l') |     */
03771 /*                      3 R_oo         ( 2l + 1 )  |              |     */
03772 /*                                                                      */
03773 /*       f(n,l;n',l') is dimensionless.                                 */
03774 /*                                                                      */
03775 /*   See for example Gordan Drake's                                     */
03776 /*      Atomic, Molecular, & Optical Physics Handbook pg.638            */
03777 /*                                                                      */
03778 /*  In the following, we have n > n'                                    */
03779 /************************************************************************/
03780 
03781 inline double OscStr_f(
03782         /*  IN THE FOLLOWING WE HAVE  n > n'                    */
03783         /* principal quantum number, 1 for ground, upper level  */
03784         long int n,
03785         /* angular momentum, 0 for s                            */
03786         long int l,
03787         /* principal quantum number, 1 for ground, lower level  */
03788         long int np,
03789         /* angular momentum, 0 for s                            */
03790         long int lp,
03791         /* Nuclear charge, 1 for H+, 2 for He++, etc            */
03792         long int iz
03793 )
03794 {
03795         double d0 = 0., d1 = 0., d2 = 0., d3 = 0., d4 = 0., d5 = 0., d6 = 0.;
03796         long int i1 = 0, i2 = 0;
03797 
03798         if( l > lp )
03799                 i1 = l;
03800         else
03801                 i1 = lp;
03802 
03803         i2 = 2*lp + 1;
03804         d0 = 1. / 3.;
03805         d1 = (double)i1 / (double)i2;
03806         /* hv() returns energy in ergs */
03807         d2 = hv( n, np, iz );
03808         d3 = d2 / EN1RYD;
03809         d4 = hri( n, l, np, lp ,iz );
03810         d5 = d4 * d4;
03811 
03812         d6 = d0 * d1 * d3 * d5;
03813 
03814         return d6;
03815 }
03816 
03817 /************************log version ***************************/
03818 inline double OscStr_f_log10( long int n , long int l , long int np , long int lp , long int iz )
03819 {
03820         double d0 = 0., d1 = 0., d2 = 0., d3 = 0., d4 = 0., d5 = 0., d6 = 0.;
03821         long int i1 = 0, i2 = 0;
03822 
03823         if( l > lp )
03824                 i1 = l;
03825         else
03826                 i1 = lp;
03827 
03828         i2 = 2*lp + 1;
03829         d0 = 1. / 3.;
03830         d1 = (double)i1 / (double)i2;
03831         /* hv() returns energy in ergs        */
03832         d2 = hv( n, np, iz );
03833         d3 = d2 / EN1RYD;
03834         d4 = hri_log10( n, l, np, lp ,iz );
03835         d5 = d4 * d4;
03836 
03837         d6 = d0 * d1 * d3 * d5;
03838 
03839         return d6;
03840 }
03841 
03842 STATIC double F21( long int a , long int b, long int c, double y, char A )
03843 {
03844         DEBUG_ENTRY( "F21()" );
03845 
03846         double d1 = 0.; 
03847         long int i1 = 0;
03848         double *yV;
03849 
03850         /**************************************************************/
03851         /*  A must be either 'a' or 'b'                               */
03852         /*  and is use to determine which                             */
03853         /*  variable recursion will be over                           */
03854         /**************************************************************/
03855 
03856         ASSERT(  A == 'a' || A == 'b' );
03857 
03858         if( A == 'b' )
03859         {
03860                 /*        if the recursion is over "b" */
03861                 /*        then make it over "a" by switching these around */
03862                 i1 = a;
03863                 a = b;
03864                 b = i1;
03865                 A = 'a';
03866         }
03867 
03868         /**************************************************************************************/
03869         /*    malloc space for the  (dynamic) 1-d array                                       */
03870         /*    2_F_1 works via recursion and needs room to store intermediate results          */
03871         /*    Here the + 5 is a safety margin                                                 */
03872         /**************************************************************************************/
03873 
03874         /*Must use CALLOC*/
03875         yV = (double*)CALLOC( sizeof(double), (size_t)(-a + 5) );
03876 
03877         /**********************************************************************************************/
03878         /*  begin sanity check, check order, and that none negative                                   */
03879         /*                                  THE GENERAL CASE                                          */
03880         /*                  USE RECURSION RELATION FOR HYPERGEOMETRIC FUNCTIONS                       */
03881         /*    for F(a,b;c;x) we have from eq.4   D. Hoang-Bing Astron. Astrophys. 238: 449-451 (1990) */
03882         /*                                                                                            */
03883         /*    (a-c) F(a-1) = a (1-x) [ F(a) - F(a-1) ] + (a + bx - c) F(a)                            */
03884         /*                                                                                            */
03885         /*                    a (1-x)                        (a + bx - c)                             */
03886         /*           F(a-1) = --------- [ F(a) - F(a-1) ] + -------------- F(a)                       */
03887         /*                     (a-c)                            (a-c)                                 */
03888         /*                                                                                            */
03889         /*                                                                                            */
03890         /*      A similiar recusion relation holds for b with a <--> b.                               */
03891         /*                                                                                            */
03892         /*                                                                                            */
03893         /*  we have initial conditions                                                                */
03894         /*                                                                                            */
03895         /*                                                                                            */
03896         /*   F(0) = 1              with a = -1                                                        */
03897         /*                                                                                            */
03898         /*                b                                                                           */
03899         /*  F(-1) = 1 - (---) x    with a = -1                                                        */
03900         /*                c                                                                           */
03901         /*                                                                                            */
03902         /*  For the first F() in the solution of the radial integral                                  */
03903         /*                                                                                            */
03904         /*        a = ( -n + l + 1 )                                                                  */
03905         /*                                                                                            */
03906         /*  a = -n + l + 1                                                                            */
03907         /*  max(a) = max(-n) + max(l)     + 1                                                         */
03908         /*         = max(-n) + max(n - 1) + 1                                                         */
03909         /*         = max(-n + n - 1)      + 1                                                         */
03910         /*         = max(-1)              + 1                                                         */
03911         /*         = 0                                                                                */
03912         /*                                                                                            */
03913         /*  similiarly                                                                                */
03914         /*                                                                                            */
03915         /*  min(a) = min(-n) + min(l)   + 1                                                           */
03916         /*         = min(-n) + 0        + 1                                                           */
03917         /*         = (-n)    + 0        + 1                                                           */
03918         /*         = -n + 1                                                                           */
03919         /*                                                                                            */
03920         /*  a -> a' + 1   implies                                                                     */
03921         /*                                                                                            */
03922         /*  max(a') = -1                                                                              */
03923         /*  min(a') = -n                                                                              */
03924         /*                                                                                            */
03925         /*  For the second F() in the solution of the radial integral                                 */
03926         /*                                                                                            */
03927         /*        a = ( -n + l - 1 )                                                                  */
03928         /*                                                                                            */
03929         /*  a = -n + l + 1                                                                            */
03930         /*  max(a) = max(-n) + max(l)   - 1                                                           */
03931         /*         = -n      + (n - 1)  - 1                                                           */
03932         /*         = -2                                                                               */
03933         /*                                                                                            */
03934         /*  similiarly                                                                                */
03935         /*                                                                                            */
03936         /*  min(a) = min(-n) + min(l)   - 1                                                           */
03937         /*         = (-n)    + 0        - 1                                                           */
03938         /*         = -n      - 1                                                                      */
03939         /*                                                                                            */
03940         /*  a -> a' + 1   implies                                                                     */
03941         /*                                                                                            */
03942         /*  max(a') = -3                                                                              */
03943         /*  min(a') = -n - 2                                                                          */
03944         /**********************************************************************************************/
03945 
03946         ASSERT( a <= 0 );
03947         ASSERT( b <= 0 );
03948         ASSERT( c >= 0 );
03949 
03950         d1 = F21i(a, b, c, y,  yV );
03951         free( yV );
03952         return d1;
03953 }
03954 
03955 STATIC mx F21_mx( long int a , long int b, long int c, double y, char A )
03956 {
03957         DEBUG_ENTRY( "F21_mx()" );
03958 
03959         mx result_mx = {0.0,0};
03960         mxq *yV = NULL;
03961 
03962         /**************************************************************/
03963         /*  A must be either 'a' or 'b'                               */
03964         /*  and is use to determine which                             */
03965         /*  variable recursion will be over                           */
03966         /**************************************************************/
03967 
03968         ASSERT(  A == 'a' || A == 'b' );
03969 
03970         if( A == 'b' )
03971         {
03972                 /*        if the recursion is over "b"                            */
03973                 /*        then make it over "a" by switching these around         */
03974                 long int i1 = a;
03975                 a = b;
03976                 b = i1;
03977                 A = 'a';
03978         }
03979 
03980         /**************************************************************************************/
03981         /*    malloc space for the  (dynamic) 1-d array                                       */
03982         /*    2_F_1 works via recursion and needs room to store intermediate results          */
03983         /*    Here the + 5 is a safety margin                                                 */
03984         /**************************************************************************************/
03985 
03986         /*Must use CALLOC*/
03987         yV = (mxq *)CALLOC( sizeof(mxq), (size_t)(-a + 5) );
03988 
03989         /**********************************************************************************************/
03990         /*  begin sanity check, check order, and that none negative                                   */
03991         /*                                  THE GENERAL CASE                                          */
03992         /*                  USE RECURSION RELATION FOR HYPERGEOMETRIC FUNCTIONS                       */
03993         /*    for F(a,b;c;x) we have from eq.4   D. Hoang-Bing Astron. Astrophys. 238: 449-451 (1990) */
03994         /*                                                                                            */
03995         /*    (a-c) F(a-1) = a (1-x) [ F(a) - F(a-1) ] + (a + bx - c) F(a)                            */
03996         /*                                                                                            */
03997         /*                    a (1-x)                        (a + bx - c)                             */
03998         /*           F(a-1) = --------- [ F(a) - F(a-1) ] + -------------- F(a)                       */
03999         /*                     (a-c)                            (a-c)                                 */
04000         /*                                                                                            */
04001         /*                                                                                            */
04002         /*      A similiar recusion relation holds for b with a <--> b.                               */
04003         /*                                                                                            */
04004         /*                                                                                            */
04005         /*  we have initial conditions                                                                */
04006         /*                                                                                            */
04007         /*                                                                                            */
04008         /*   F(0) = 1              with a = -1                                                        */
04009         /*                                                                                            */
04010         /*                b                                                                           */
04011         /*  F(-1) = 1 - (---) x    with a = -1                                                        */
04012         /*                c                                                                           */
04013         /*                                                                                            */
04014         /*  For the first F() in the solution of the radial integral                                  */
04015         /*                                                                                            */
04016         /*        a = ( -n + l + 1 )                                                                  */
04017         /*                                                                                            */
04018         /*  a = -n + l + 1                                                                            */
04019         /*  max(a) = max(-n) + max(l)     + 1                                                         */
04020         /*         = max(-n) + max(n - 1) + 1                                                         */
04021         /*         = max(-n + n - 1)      + 1                                                         */
04022         /*         = max(-1)              + 1                                                         */
04023         /*         = 0                                                                                */
04024         /*                                                                                            */
04025         /*  similiarly                                                                                */
04026         /*                                                                                            */
04027         /*  min(a) = min(-n) + min(l)   + 1                                                           */
04028         /*         = min(-n) + 0        + 1                                                           */
04029         /*         = (-n)    + 0        + 1                                                           */
04030         /*         = -n + 1                                                                           */
04031         /*                                                                                            */
04032         /*  a -> a' + 1   implies                                                                     */
04033         /*                                                                                            */
04034         /*  max(a') = -1                                                                              */
04035         /*  min(a') = -n                                                                              */
04036         /*                                                                                            */
04037         /*  For the second F() in the solution of the radial integral                                 */
04038         /*                                                                                            */
04039         /*        a = ( -n + l - 1 )                                                                  */
04040         /*                                                                                            */
04041         /*  a = -n + l + 1                                                                            */
04042         /*  max(a) = max(-n) + max(l)   - 1                                                           */
04043         /*         = -n      + (n - 1)  - 1                                                           */
04044         /*         = -2                                                                               */
04045         /*                                                                                            */
04046         /*  similiarly                                                                                */
04047         /*                                                                                            */
04048         /*  min(a) = min(-n) + min(l)   - 1                                                           */
04049         /*         = (-n)    + 0        - 1                                                           */
04050         /*         = -n      - 1                                                                      */
04051         /*                                                                                            */
04052         /*  a -> a' + 1   implies                                                                     */
04053         /*                                                                                            */
04054         /*  max(a') = -3                                                                              */
04055         /*  min(a') = -n - 2                                                                          */
04056         /**********************************************************************************************/
04057 
04058         ASSERT( a <= 0 );
04059         ASSERT( b <= 0 );
04060         ASSERT( c >= 0 );
04061 
04062         result_mx = F21i_log(a, b, c, y,  yV );
04063         free( yV );
04064         return result_mx;
04065 }
04066 
04067 STATIC double F21i(long int a, long int b, long int c, double y, double *yV )
04068 {
04069         DEBUG_ENTRY( "F21i()" );
04070 
04071         double d0 = 0., d1 = 0., d2 = 0., d3 = 0., d4 = 0., d5 = 0.;
04072         double d8 = 0., d9 = 0., d10 = 0., d11 = 0., d12 = 0., d13 = 0., d14 = 0.;
04073         long int i1 = 0, i2 = 0;
04074 
04075         if( a == 0 )
04076         {
04077                 return 1.;
04078         }
04079         else if( a == -1 )
04080         {
04081                 ASSERT( c != 0 );
04082                 d1 = (double)b;
04083                 d2 = (double)c;
04084                 d3 = y * (d1/d2);
04085                 d4 = 1. - d3;
04086                 return d4;
04087         }
04088         /* Check to see if y(-a) != 0 in a very round about way to avoid lclint:error:13 */
04089         else if( yV[-a] != 0. )
04090         {
04091                 /* Return the stored result */
04092                 return yV[-a];
04093         }
04094         else
04095         {
04096                 /******************************************************************************************/
04097                 /*                             -             -                                            */
04098                 /*             (a)(1 - y)     |               |       (a + bx + c)                        */
04099                 /*   F(a-1) = --------------  | F(a) - F(a+1) | +   --------------- F(a+1)                */
04100                 /*               (a - c)      |               |        (a - c)                            */
04101                 /*                             -             -                                            */
04102                 /*                                                                                        */
04103                 /*                                                                                        */
04104                 /*                                                                                        */
04105                 /*                                                                                        */
04106                 /*                                                                                        */
04107                 /*   with     F(0) = 1                                                                    */
04108                 /*                         b                                                              */
04109                 /*   and     F(-1) = 1 - (---) y                                                          */
04110                 /*                         c                                                              */
04111                 /*                                                                                        */
04112                 /*                                                                                        */
04113                 /*                                                                                        */
04114                 /*   Use a -> a' + 1                                                                      */
04115                 /*                               _                 _                                      */
04116                 /*           (a' + 1) (1  - x)  |                   |    (a' + 1 + bx - c)                */
04117                 /*   F(a') = -----------------  | F(a'+1) - F(a'+2) | +  ----------------- F(a'+1)        */
04118                 /*              (a' + 1 - c)    |                   |      (a' + 1 - c)                   */
04119                 /*                               -                 -                                      */
04120                 /*                                                                                        */
04121                 /*   For the first F() in the solution of the radial integral                             */
04122                 /*                                                                                        */
04123                 /*         a = ( -n + l + 1 )                                                             */
04124                 /*                                                                                        */
04125                 /*   a = -n + l + 1                                                                       */
04126                 /*   max(a) = max(-n) + max(l)     + 1                                                    */
04127                 /*          = -n      + max(n-1)   + 1                                                    */
04128                 /*          = -n      + n-1        + 1                                                    */
04129                 /*          = 0                                                                           */
04130                 /*                                                                                        */
04131                 /*   similiarly                                                                           */
04132                 /*                                                                                        */
04133                 /*   min(a) = min(-n)   + min(l)   + 1                                                    */
04134                 /*          = min(-n)   + 0        + 1                                                    */
04135                 /*          = -n + 1                                                                      */
04136                 /*                                                                                        */
04137                 /*   a -> a' + 1   implies                                                                */
04138                 /*                                                                                        */
04139                 /*   max(a') = -1                                                                         */
04140                 /*   min(a') = -n                                                                         */
04141                 /******************************************************************************************/
04142 
04143                 i1= a + 1;
04144                 i2= a + 1 - c;
04145                 d0= (double)i2;
04146                 ASSERT( i2 != 0 );
04147                 d1= 1. - y;
04148                 d2= (double)i1 * d1;
04149                 d3= d2 / d0;
04150                 d4= (double)b * y;
04151                 d5= d0 + d4;
04152 
04153                 d8= F21i( (long int)(a + 1), b, c, y, yV );
04154                 d9= F21i( (long int)(a + 2), b, c, y, yV );
04155 
04156                 d10= d8 - d9;
04157                 d11= d3 * d10;
04158                 d12= d5 / d0;
04159                 d13= d12 * d8;
04160                 d14= d11 + d13;
04161 
04162                 /* Store the result for later use */
04163                 yV[-a] = d14;
04164                 return d14;
04165         }
04166 }
04167 
04168 STATIC mx F21i_log( long int a, long int b, long int c, double y, mxq *yV )
04169 {
04170         DEBUG_ENTRY( "F21i_log()" );
04171 
04172         mx result_mx = {0.0,0};
04173 
04174         if( yV[-a].q != 0. )
04175         {
04176                 /* Return the stored result   */
04177                 return yV[-a].mx;
04178         }
04179         else if( a == 0 )
04180         {
04181                 ASSERT( yV[-a].q == 0. );
04182 
04183                 result_mx.m = 1.;
04184                 result_mx.x = 0;
04185 
04186                 ASSERT( yV[-a].mx.m == 0. );
04187                 ASSERT( yV[-a].mx.x == 0 );
04188 
04189                 yV[-a].q = 1;
04190                 yV[-a].mx = result_mx;
04191                 return result_mx;
04192         }
04193         else if( a == -1 )
04194         {
04195                 double d1 = (double)b;
04196                 double d2 = (double)c;
04197                 double d3 = y * (d1/d2);
04198 
04199                 ASSERT( yV[-a].q == 0. );
04200                 ASSERT( c != 0 );
04201                 ASSERT( y != 0. );
04202 
04203                 result_mx.m = 1. - d3;
04204                 result_mx.x = 0;
04205 
04206                 while ( fabs(result_mx.m) > 1.0e+25 )
04207                 {
04208                         result_mx.m /= 1.0e+25;
04209                         result_mx.x += 25;
04210                 }
04211 
04212                 ASSERT( yV[-a].mx.m == 0. );
04213                 ASSERT( yV[-a].mx.x == 0 );
04214 
04215                 yV[-a].q = 1;
04216                 yV[-a].mx = result_mx;
04217                 return result_mx;
04218         }
04219         else
04220         {
04221                 /******************************************************************************************/
04222                 /*                             -             -                                            */
04223                 /*             (a)(1 - y)     |               |       (a + bx + c)                        */
04224                 /*   F(a-1) = --------------  | F(a) - F(a+1) | +   --------------- F(a+1)                */
04225                 /*               (a - c)      |               |         (a - c)                           */
04226                 /*                             -             -                                            */
04227                 /*                                                                                        */
04228                 /*                                                                                        */
04229                 /*   with     F(0) = 1                                                                    */
04230                 /*                         b                                                              */
04231                 /*   and     F(-1) = 1 - (---) y                                                          */
04232                 /*                         c                                                              */
04233                 /*                                                                                        */
04234                 /*                                                                                        */
04235                 /*                                                                                        */
04236                 /*   Use a -> a' + 1                                                                      */
04237                 /*                               _                 _                                      */
04238                 /*           (a' + 1) (1  - x)  |                   |    (a' + 1 + bx - c)                */
04239                 /*   F(a') = -----------------  | F(a'+1) - F(a'+2) | +  ----------------- F(a'+1)        */
04240                 /*              (a' + 1 - c)    |                   |      (a' + 1 - c)                   */
04241                 /*                               -                 -                                      */
04242                 /*                                                                                        */
04243                 /*   For the first F() in the solution of the radial integral                             */
04244                 /*                                                                                        */
04245                 /*         a = ( -n + l + 1 )                                                             */
04246                 /*                                                                                        */
04247                 /*   a = -n + l + 1                                                                       */
04248                 /*   max(a) = max(-n) + max(l)     + 1                                                    */
04249                 /*          = -n      + max(n-1)   + 1                                                    */
04250                 /*          = -n      + n-1        + 1                                                    */
04251                 /*          = 0                                                                           */
04252                 /*                                                                                        */
04253                 /*   similiarly                                                                           */
04254                 /*                                                                                        */
04255                 /*   min(a) = min(-n)   + min(l)   + 1                                                    */
04256                 /*          = min(-n)   + 0        + 1                                                    */
04257                 /*          = -n + 1                                                                      */
04258                 /*                                                                                        */
04259                 /*   a -> a' + 1   implies                                                                */
04260                 /*                                                                                        */
04261                 /*   max(a') = -1                                                                         */
04262                 /*   min(a') = -n                                                                         */
04263                 /******************************************************************************************/
04264 
04265                 mx d8 = {0.0,0}, d9 = {0.0,0}, d10 = {0.0,0}, d11 = {0.0,0};
04266 
04267                 double db = (double)b;
04268                 double d00 = (double)(a + 1 - c);
04269                 double d0 = (double)(a + 1);
04270                 double d1 = 1. - y;
04271                 double d2 = d0 * d1;
04272                 double d3 = d2 / d00;
04273                 double d4 = db * y;
04274                 double d5 = d00 + d4;
04275                 double d6 = d5 / d00;
04276 
04277                 ASSERT( yV[-a].q == 0. );
04278 
04279                 /******************************************************************************************/
04280                 /*                               _                 _                                      */
04281                 /*           (a' + 1) (1  - x)  |                   |    (a' + 1 - c) + b*x               */
04282                 /*   F(a') = -----------------  | F(a'+1) - F(a'+2) | +  ------------------ F(a'+1)       */
04283                 /*              (a' + 1 - c)    |                   |      (a' + 1 - c)                   */
04284                 /*                               -                 -                                      */
04285                 /******************************************************************************************/
04286 
04287                 d8= F21i_log( (a + 1), b, c, y, yV );
04288                 d9= F21i_log( (a + 2), b, c, y, yV );
04289 
04290                 if( (d8.m) != 0. )
04291                 {
04292                         d10.x = d8.x;
04293                         d10.m = d8.m * (1. - (d9.m/d8.m) * powi( 10., (d9.x - d8.x)));
04294                 }
04295                 else
04296                 {
04297                         d10.m = -d9.m;
04298                         d10.x = d9.x;
04299                 }
04300 
04301                 d10.m *= d3;
04302 
04303                 d11.x = d8.x;
04304                 d11.m = d6 * d8.m;
04305 
04306                 if(  (d11.m) != 0. )
04307                 {
04308                         result_mx.x = d11.x;
04309                         result_mx.m = d11.m * (1. + (d10.m/d11.m) * powi( 10. , (d10.x - d11.x) ) );
04310                 }
04311                 else
04312                 {
04313                         result_mx = d10;
04314                 }
04315 
04316                 while ( fabs(result_mx.m) > 1.0e+25 )
04317                 {
04318                         result_mx.m /= 1.0e+25;
04319                         result_mx.x += 25;
04320                 }
04321 
04322                 /* Store the result for later use                */
04323                 yV[-a].q = 1;
04324                 yV[-a].mx = result_mx;
04325                 return result_mx;
04326         }
04327 }
04328 
04329 /********************************************************************************/
04330 
04331 inline void normalize_mx( mx& target )
04332 {
04333         while( fabs(target.m) > 1.0e+25 )
04334         {
04335                 target.m /= 1.0e+25;
04336                 target.x += 25;
04337         }
04338         while( fabs(target.m) < 1.0e-25 )
04339         {
04340                 target.m *= 1.0e+25;
04341                 target.x -= 25;
04342         }
04343         return;
04344 }
04345 
04346 inline mx add_mx( const mx& a, const mx& b )
04347 {
04348         mx result = {0.0,0};
04349 
04350         if( a.m != 0. )
04351         {
04352                 result.x = a.x;
04353                 result.m = a.m * (1. + (b.m/a.m) * powi( 10. , (b.x - a.x) ) );
04354         }
04355         else
04356         {
04357                 result = b;
04358         }
04359         normalize_mx( result );
04360         return result;
04361 }
04362 
04363 inline mx sub_mx( const mx& a, const mx& b )
04364 {
04365         mx result = {0.0,0};
04366         mx minusb = b;
04367         minusb.m = -minusb.m;
04368 
04369         result = add_mx( a, minusb );
04370         normalize_mx( result );
04371 
04372         return result;
04373 }
04374 
04375 inline mx mxify( double a )
04376 {
04377         mx result_mx = {0.0,0};
04378 
04379         result_mx.x = 0;
04380         result_mx.m = a;
04381         normalize_mx( result_mx );
04382 
04383         return result_mx;
04384 }
04385 
04386 inline double unmxify( const mx& a_mx )
04387 {
04388         return a_mx.m * powi( 10., a_mx.x );
04389 }
04390 
04391 inline mx mxify_log10( double log10_a )
04392 {
04393         mx result_mx = {0.0,0};
04394 
04395         while ( log10_a > 25.0 )
04396         {
04397                 log10_a -= 25.0;
04398                 result_mx.x += 25;
04399         }
04400 
04401         while ( log10_a < -25.0 )
04402         {
04403                 log10_a += 25.0;
04404                 result_mx.x -= 25;
04405         }
04406 
04407         result_mx.m = pow(10., log10_a);
04408 
04409         return result_mx;
04410 }
04411 
04412 inline mx mult_mx( const mx& a, const mx& b )
04413 {
04414         mx result = {0.0,0};
04415 
04416         result.m = (a.m * b.m);
04417         result.x = (a.x + b.x);
04418         normalize_mx( result );
04419 
04420         return result;
04421 }
04422 
04423 inline double log10_prodxx( long int lp, double Ksqrd )
04424 {
04425         /**********************************************************************/
04426         /*        |  s=l'                |     s=l'                           */
04427         /*        | -----                |     ---                            */
04428         /*  log10 |  | |  (1 + s^2 K^2)  | =    >    log10((1 + s^2 K^2))     */
04429         /*        |  | |                 |     ---                            */
04430         /*        |  s=0                 |     s=0                            */
04431         /**********************************************************************/
04432 
04433         if( lp == 0 )
04434                 return 0.;
04435 
04436         double partsum = 0.;
04437         for( long int s = 1; s <= lp; s++ )
04438         {
04439                 double s2 = pow2((double)s);
04440                 partsum += log10( 1. + s2*Ksqrd );
04441 
04442                 ASSERT( partsum >= 0. );
04443         }
04444         return partsum;
04445 }

Generated on Mon Feb 16 12:01:17 2009 for cloudy by  doxygen 1.4.7