| [3115] | 1 | #include "machdefs.h"
 | 
|---|
 | 2 | #include <iostream>
 | 
|---|
 | 3 | #include <stdlib.h>
 | 
|---|
 | 4 | #include <stdio.h>
 | 
|---|
 | 5 | #include <string.h>
 | 
|---|
 | 6 | #include <math.h>
 | 
|---|
 | 7 | 
 | 
|---|
 | 8 | #include "pexceptions.h"
 | 
|---|
 | 9 | 
 | 
|---|
 | 10 | #include "constcosmo.h"
 | 
|---|
 | 11 | #include "planckspectra.h"
 | 
|---|
 | 12 | 
 | 
|---|
| [3325] | 13 | namespace SOPHYA {
 | 
|---|
 | 14 | 
 | 
|---|
| [3115] | 15 | /*
 | 
|---|
 | 16 | ----------------------------------------------------------------
 | 
|---|
 | 17 | - UNITES:
 | 
|---|
 | 18 |      Temperature en Kelvin  "K"
 | 
|---|
 | 19 |      Frequence en GigaHertz  "Hz"
 | 
|---|
 | 20 |      Longueur d'onde en Metre  "m"
 | 
|---|
 | 21 | ----------------------------------------------------------------
 | 
|---|
 | 22 | - Frequence / Longeur d'onde
 | 
|---|
 | 23 |  l = c/f ; f = c/l
 | 
|---|
 | 24 |  dl = c/f^2 df = l^2/c df
 | 
|---|
 | 25 |  df = c/l^2 dl = f^2/c dl
 | 
|---|
 | 26 |  P[f] df = P[l] dl = P[f] c/l^2 dl = P[l] c/f^2 df
 | 
|---|
 | 27 | ----------------------------------------------------------------
 | 
|---|
 | 28 | - Lois de Planck Wien et Rayleigh
 | 
|---|
 | 29 |      Planck   H*Nu/(K*T) = H*C/(Lambda*K*T) quelconque
 | 
|---|
 | 30 |      Wien     H*Nu/(K*T) = H*C/(Lambda*K*T) >> 1
 | 
|---|
 | 31 |      Rayleigh H*Nu/(K*T) = H*C/(Lambda*K*T) << 1
 | 
|---|
 | 32 | ----------------------------------------------------------------
 | 
|---|
 | 33 | - Les termes en facteur pour les lois de Planck Wien et Rayleigh
 | 
|---|
 | 34 |         (la partie contenant l'exponentielle)
 | 
|---|
 | 35 |  ainsi que pour les derivees des ces termes par rapport a la temperature
 | 
|---|
 | 36 |  Planck:   1/[exp(H*f/(K*t))-1] = 1/[exp(HC/(l*K*t))-1]
 | 
|---|
 | 37 |      der=  H*f/(K*t) /t * exp(HC/(l*K*t))/[exp(HC/(l*K*t))-1]^2
 | 
|---|
 | 38 |  Wien:     1/exp(H*f/(K*t))
 | 
|---|
 | 39 |      der=  H*f/(K*t) /t /exp(H*f/(K*t))
 | 
|---|
 | 40 |  Rayleigh: 1/(H*f/(K*t))
 | 
|---|
 | 41 |      der=  K/(H*f)
 | 
|---|
 | 42 |  Pour x->0: compute exp(x)=1+x+x^2/2 for 1/(exp(x)-1)
 | 
|---|
 | 43 |             soit 1/(exp(x)-1)  -> 1/(x+x^2/2)
 | 
|---|
 | 44 |   car exp(x)-1 vaut zero plus vite que son DL a cause de la soustraction
 | 
|---|
 | 45 | ----------------------------------------------------------------
 | 
|---|
 | 46 |  - RADIANCE (Brillance) en fonction de nu ou lambda
 | 
|---|
 | 47 |  nombre de watts (ou photons par seconde)
 | 
|---|
 | 48 |  radies par unite de surface par steradian et par hertz (ou metre)
 | 
|---|
 | 49 |     2*f^2/c^2   * 1/(exp()-1)    ph/s/m^2/Sr/Hz
 | 
|---|
 | 50 |     2*h*f^3/c^2 * 1/(exp()-1)    W/m^2/Sr/Hz
 | 
|---|
 | 51 |     2*c/l^4     * 1/(exp()-1)    ph/s/m^2/Sr/m
 | 
|---|
 | 52 |     2*h*c^2/l^5 * 1/(exp()-1)    W/m^2/Sr/m
 | 
|---|
 | 53 | ----------------------------------------------------------------
 | 
|---|
 | 54 |  - EMITTANCE en fonction de nu ou lambda
 | 
|---|
 | 55 |  nombre de watts (ou photons par seconde)
 | 
|---|
 | 56 |  radies dans un hemisphere (2*PI sr)
 | 
|---|
 | 57 |  par unite de surface et par hertz (ou metre)
 | 
|---|
 | 58 |  ..quand on integre sur 2Pi sr il faut
 | 
|---|
 | 59 |  ..multiplier par cos(theta)  -> facteur Pi uniquement
 | 
|---|
 | 60 |     EMITTANCE = Pi * RADIANCE
 | 
|---|
 | 61 |     2*Pi*f^2/c^2   * 1/(exp()-1)    ph/s/m^2/Hz
 | 
|---|
 | 62 |     2*Pi*h*f^3/c^2 * 1/(exp()-1)    W/m^2/Hz
 | 
|---|
 | 63 |     2*Pi*c/l^4     * 1/(exp()-1)    ph/s/m^2/m
 | 
|---|
 | 64 |     2*Pi*h*c^2/l^5 * 1/(exp()-1)    W/m^2/m
 | 
|---|
 | 65 | ----------------------------------------------------------------
 | 
|---|
 | 66 |  - DENSITE en fonction de nu ou lambda
 | 
|---|
 | 67 |  nombre de joules (ou photons) par m^3  et par hertz (ou metre)
 | 
|---|
 | 68 |    DENSITE = 4*Pi/c * RADIANCE
 | 
|---|
 | 69 |    8*Pi*f^2/c^3    * 1/(exp()-1)    ph/m^3/Hz
 | 
|---|
 | 70 |    8*Pi*h*f^3/c^3  * 1/(exp()-1)    J/m^3/Hz
 | 
|---|
 | 71 |    8*Pi/l^4        * 1/(exp()-1)    ph/m^3/m
 | 
|---|
 | 72 |    8*Pi*h*c/l^5    * 1/(exp()-1)    J/m^3/m
 | 
|---|
 | 73 | ----------------------------------------------------------------
 | 
|---|
 | 74 |  - DENSITE d'energie totale  (loi de Stefan-Boltzman)
 | 
|---|
 | 75 |    4*sigma*T^4/C   J/m^3
 | 
|---|
 | 76 |    Sigma = 2*PI^5*K^4/(15.*C^2*H^3) = PI^2*K^4/(60.*Hbar^3*C2)
 | 
|---|
 | 77 | ----------------------------------------------------------------
 | 
|---|
 | 78 | */
 | 
|---|
 | 79 | 
 | 
|---|
 | 80 | /*
 | 
|---|
 | 81 | POUR TESTER LES LIMITES DE L'EXPONENTIELLE:
 | 
|---|
 | 82 | 1-/ copier/coller les lignes suivantes dans toto.icc
 | 
|---|
 | 83 | double x=10.;
 | 
|---|
 | 84 | for(int i=0;i<35;i++) {
 | 
|---|
 | 85 |   double ex = exp(x);
 | 
|---|
 | 86 |   double exm1a = x*(1.+x/2.*(1.+x/3.)),;
 | 
|---|
 | 87 |   printf("x=%g exp(x)=%e exp(x)-1=%e dl=%e (d=%e)\n",x,ex,ex-1.,exm1a,ex-1.-exm1a);
 | 
|---|
 | 88 |   x /= 10.;
 | 
|---|
 | 89 | }
 | 
|---|
 | 90 | 2-/ executer sous spiapp: > c++execfrf toto.icc
 | 
|---|
 | 91 | */
 | 
|---|
 | 92 | 
 | 
|---|
 | 93 | 
 | 
|---|
 | 94 | #define MAXARGEXP 100.    /* maxi = 709.7827128933840 */
 | 
|---|
 | 95 | #define MINARGEXP 1.e-10  /* Replace exp(x) by DL for 1/(exp(x)-1) when x->0 */
 | 
|---|
 | 96 | 
 | 
|---|
 | 97 | //************************************************************************
 | 
|---|
 | 98 | // vitesse de la lumiere en m/s
 | 
|---|
 | 99 | double CinM_ = SpeedOfLight_Cst*1e+3;
 | 
|---|
 | 100 | // h/k pour une frequence en Hz
 | 
|---|
 | 101 | double HsK_ = h_Planck_Cst/k_Boltzman_Cst;
 | 
|---|
 | 102 | // hc/k pour une longeur d'onde en metre
 | 
|---|
 | 103 | double HCsK_ = h_Planck_Cst*CinM_/k_Boltzman_Cst;
 | 
|---|
 | 104 | 
 | 
|---|
 | 105 | //************************************************************************
 | 
|---|
 | 106 | PlanckSpectra::PlanckSpectra(double T)
 | 
|---|
| [3347] | 107 |   : T_(T) , spectraapprox_(PLANCK) , spectrafunc_(VALUE) , spectravar_(NU)
 | 
|---|
 | 108 |   , spectraunit_(ANGSFLUX) , spectrapower_(POWER)
 | 
|---|
| [3115] | 109 | {
 | 
|---|
 | 110 | }
 | 
|---|
 | 111 | 
 | 
|---|
 | 112 | PlanckSpectra::PlanckSpectra(PlanckSpectra& s)
 | 
|---|
| [3347] | 113 |   : T_(s.T_) , spectraapprox_(s.spectraapprox_) , spectrafunc_(s.spectrafunc_) , spectravar_(s.spectravar_)
 | 
|---|
 | 114 |   , spectraunit_(s.spectraunit_), spectrapower_(s.spectrapower_)
 | 
|---|
| [3115] | 115 | {
 | 
|---|
 | 116 | }
 | 
|---|
 | 117 | 
 | 
|---|
 | 118 | PlanckSpectra::~PlanckSpectra(void)
 | 
|---|
 | 119 | {
 | 
|---|
 | 120 | }
 | 
|---|
 | 121 | 
 | 
|---|
 | 122 | //************************************************************************
 | 
|---|
| [3347] | 123 | void PlanckSpectra::SetSpectraApprox(SpectraApprox spectraapprox)
 | 
|---|
 | 124 | // spectraapprox = PLANCK   : Planck spectra
 | 
|---|
 | 125 | //               = RAYLEIGH : Rayleigh spectra
 | 
|---|
 | 126 | //               = WIEN     : Wien spectra
 | 
|---|
| [3115] | 127 | {
 | 
|---|
| [3347] | 128 |   spectraapprox_ = spectraapprox;
 | 
|---|
| [3115] | 129 | }
 | 
|---|
 | 130 | 
 | 
|---|
| [3347] | 131 | void PlanckSpectra::SetSpectraFunc(SpectraFunc spectrafunc)
 | 
|---|
 | 132 | // spectrafunc = VALUE : spectra
 | 
|---|
 | 133 | //             = DERIV : derivative of spectra relative to temperature
 | 
|---|
| [3115] | 134 | {
 | 
|---|
| [3347] | 135 |   spectrafunc_ = spectrafunc;
 | 
|---|
| [3115] | 136 | }
 | 
|---|
 | 137 | 
 | 
|---|
| [3347] | 138 | void PlanckSpectra::SetSpectraVar(SpectraVar spectravar)
 | 
|---|
 | 139 | // spectravar = NU     : variable is frequency (Hz)
 | 
|---|
 | 140 | //            = LAMBDA : variable is wavelength (m)
 | 
|---|
| [3115] | 141 | {
 | 
|---|
| [3347] | 142 |   spectravar_ = spectravar;
 | 
|---|
| [3115] | 143 | }
 | 
|---|
 | 144 | 
 | 
|---|
| [3347] | 145 | void PlanckSpectra::SetSpectraPower(SpectraPower spectrapower)
 | 
|---|
 | 146 | // spectrapower = POWER : in W/...
 | 
|---|
 | 147 | //              = PHOTON : in photon/s/...
 | 
|---|
| [3115] | 148 | {
 | 
|---|
| [3347] | 149 |   spectrapower_ = spectrapower;
 | 
|---|
| [3115] | 150 | }
 | 
|---|
 | 151 | 
 | 
|---|
| [3347] | 152 | void PlanckSpectra::SetSpectraUnit(SpectraUnit spectraunit)
 | 
|---|
 | 153 | // spectraunit = ANGSFLUX  : radiance   W/m^2/Sr/Hz  or ...
 | 
|---|
 | 154 | //             = SFLUX     : emittance  W/m^2/Hz     or ... 
 | 
|---|
 | 155 | //             = DENSENERG : density    J/m^3/Hz     or ...
 | 
|---|
 | 156 | //             = EXPON     : just the function exp() or equivalent for Rayleigh
 | 
|---|
| [3115] | 157 | {
 | 
|---|
| [3347] | 158 |   spectraunit_ = spectraunit;
 | 
|---|
| [3115] | 159 | }
 | 
|---|
 | 160 | 
 | 
|---|
 | 161 | 
 | 
|---|
 | 162 | //************************************************************************
 | 
|---|
 | 163 | double PlanckSpectra::F2L(double nu_or_lambda)
 | 
|---|
 | 164 | // Convert frequency (GHz) to/from Wavelength (m)
 | 
|---|
 | 165 | // Lambda(m) * Nu(GHz) = C(km/s) * 10^-6
 | 
|---|
 | 166 | {
 | 
|---|
 | 167 |   return CinM_ / nu_or_lambda;
 | 
|---|
 | 168 | }
 | 
|---|
 | 169 | 
 | 
|---|
 | 170 | //************************************************************************
 | 
|---|
 | 171 | double PlanckSpectra::PlanckExp(double fl)
 | 
|---|
 | 172 | {
 | 
|---|
| [3347] | 173 |   double x = (spectravar_==LAMBDA) ? HCsK_/(fl*T_) : HsK_*fl/T_;
 | 
|---|
| [3115] | 174 | 
 | 
|---|
| [3347] | 175 |   if(spectraapprox_ == RAYLEIGH) return 1./x;  // Rayleigh
 | 
|---|
| [3115] | 176 | 
 | 
|---|
 | 177 |   if(x>MAXARGEXP) return 0.;
 | 
|---|
 | 178 | 
 | 
|---|
| [3347] | 179 |   if(spectraapprox_ == WIEN) return exp(-x);  // Wien
 | 
|---|
| [3115] | 180 | 
 | 
|---|
 | 181 |   if(x<MINARGEXP) return 1./(x*(1.+x/2.));
 | 
|---|
 | 182 |   return 1./(exp(x)-1.);
 | 
|---|
 | 183 | }
 | 
|---|
 | 184 | 
 | 
|---|
 | 185 | double PlanckSpectra::DPlanckExp_DT(double fl)
 | 
|---|
 | 186 | {
 | 
|---|
| [3347] | 187 |   if(spectraapprox_ == RAYLEIGH)
 | 
|---|
 | 188 |     return (spectravar_==LAMBDA) ? fl/HCsK_: 1. / (HsK_*fl);  // Rayleigh
 | 
|---|
| [3115] | 189 | 
 | 
|---|
| [3347] | 190 |   double x = (spectravar_==LAMBDA) ? HCsK_/(fl*T_) : HsK_*fl/T_;
 | 
|---|
| [3115] | 191 | 
 | 
|---|
 | 192 |   if(x>MAXARGEXP) return 0.;
 | 
|---|
 | 193 | 
 | 
|---|
| [3347] | 194 |   if(spectraapprox_ == WIEN) return x/T_ * exp(-x);  // Wien
 | 
|---|
| [3115] | 195 | 
 | 
|---|
 | 196 |   double v;
 | 
|---|
 | 197 |   if(x<MINARGEXP) { // 1/(exp(x)-1)  -derive-> -exp(x)/(exp(x)-1)^2
 | 
|---|
 | 198 |     v = x*(1.+x/2.);
 | 
|---|
 | 199 |     return x/T_ * (1.+v)/(v*v);
 | 
|---|
 | 200 |   }
 | 
|---|
 | 201 |   v = exp(x);
 | 
|---|
 | 202 |   return x/T_ * v/((v-1.)*(v-1.));  
 | 
|---|
 | 203 | }
 | 
|---|
 | 204 | 
 | 
|---|
 | 205 | //------------------------------------------------------------
 | 
|---|
 | 206 | double PlanckSpectra::operator() (double x)
 | 
|---|
 | 207 | {
 | 
|---|
 | 208 |   // --- type de spectre et d'approximation selon choix variable
 | 
|---|
| [3347] | 209 |   double fex = (spectrafunc_==DERIV) ? DPlanckExp_DT(x): PlanckExp(x);
 | 
|---|
| [3115] | 210 | 
 | 
|---|
 | 211 |   // --- le coefficient multiplicateur devant l'expo
 | 
|---|
| [3347] | 212 |   if(spectraunit_ == EXPON) return fex;  // expo seule
 | 
|---|
| [3115] | 213 | 
 | 
|---|
| [3347] | 214 |   // radiance en ph/...               longeur d'onde         frequency
 | 
|---|
 | 215 |   double coeff = (spectravar_==LAMBDA) ? 2.*CinM_/(x*x*x*x): 2.*x*x/(CinM_*CinM_);
 | 
|---|
| [3115] | 216 | 
 | 
|---|
| [3347] | 217 |   if(spectraunit_ == SFLUX)      coeff *= M_PI;  // emittance en ph/...
 | 
|---|
 | 218 |   else if(spectraunit_ == DENSENERG) coeff *= 4.*M_PI/CinM_;  // densite en ph/...
 | 
|---|
| [3115] | 219 | 
 | 
|---|
| [3347] | 220 |   // unite en W/...                longeur d'onde         frequency
 | 
|---|
 | 221 |   if(spectrapower_ == POWER)
 | 
|---|
 | 222 |     coeff *= (spectravar_==LAMBDA) ? h_Planck_Cst*CinM_/x: h_Planck_Cst*x;
 | 
|---|
| [3115] | 223 | 
 | 
|---|
 | 224 |   return coeff * fex;
 | 
|---|
 | 225 | }
 | 
|---|
 | 226 | 
 | 
|---|
 | 227 | //------------------------------------------------------------
 | 
|---|
 | 228 | double PlanckSpectra::PlanckEnergie(void)
 | 
|---|
 | 229 | //  densite d'energie: energie par m^3  en "J / m^3"
 | 
|---|
 | 230 | // cste de Stefan-Boltzmann en W/m^2/K^4
 | 
|---|
 | 231 | {
 | 
|---|
 | 232 |   return 4.*StefBoltz_Cst*T_*T_*T_*T_/(SpeedOfLight_Cst*1000.);
 | 
|---|
 | 233 | }
 | 
|---|
 | 234 | 
 | 
|---|
 | 235 | //------------------------------------------------------------
 | 
|---|
 | 236 | double PlanckSpectra::PlanckPhoton(void)
 | 
|---|
 | 237 | //  densite de photons: nombre de photons par m^3  en "ph / m^3"
 | 
|---|
 | 238 | {
 | 
|---|
 | 239 |   double x = k_Boltzman_Cst*T_/(h_Planck_Cst*SpeedOfLight_Cst*1000.);
 | 
|---|
 | 240 |   return 16.*M_PI*Zeta_3_Cst* x*x*x;
 | 
|---|
 | 241 | }
 | 
|---|
 | 242 | 
 | 
|---|
 | 243 | double PlanckSpectra::WienLaw(void)
 | 
|---|
 | 244 | // Retourne la frequence (ou longeur d'onde) du maximum
 | 
|---|
 | 245 | // du spectre de radiance (ou emittance ou densite).
 | 
|---|
 | 246 | // La valeur du maximum depend de l'unite du spectre (W/... ou Ph/s/...)
 | 
|---|
 | 247 | /*
 | 
|---|
 | 248 | --- Les fonctions:
 | 
|---|
 | 249 | En frequence: n = 3  en W/...  ,  n = 2  en Ph/...
 | 
|---|
 | 250 | En longueur d'onde: n = 5  en W/...  ,  n = 4  en Ph/...
 | 
|---|
 | 251 | f[x_] := x^n*Exp[-x]; Solve[f'[x]==0,x]   // Wien
 | 
|---|
 | 252 | f[x_] := x^n/(Exp[x]-1); NSolve[f'[x]==0,x,17]  // Planck
 | 
|---|
 | 253 | La derivee par rapport a T des fonctions en frequence:
 | 
|---|
 | 254 | df/dT[x_] := x^(n+1)*Exp[-x]; Solve[f'[x]==0,x]  // Wien
 | 
|---|
 | 255 | df/dT[x_] := x^(n+1)*Exp[x]/(Exp[x]-1)^2; NSolve[f'[x]==0,x,17]  // Planck
 | 
|---|
 | 256 | */
 | 
|---|
 | 257 | {
 | 
|---|
 | 258 |   double x=-1.;
 | 
|---|
| [3347] | 259 |   if(spectravar_ == NU) { // Frequence
 | 
|---|
 | 260 |     if(spectrafunc_ == VALUE) {  // Le spectre
 | 
|---|
 | 261 |       if(spectrapower_ == POWER) //  W/...
 | 
|---|
 | 262 |         {if(spectraapprox_==PLANCK) x=2.82143938074; else if(spectraapprox_==WIEN) x=3.;}
 | 
|---|
 | 263 |       else if(spectrapower_ == PHOTON) //  Ph/s/...
 | 
|---|
 | 264 |         {if(spectraapprox_==PLANCK) x=1.59362426; else if(spectraapprox_==WIEN) x=2.;}
 | 
|---|
 | 265 |     } else if(spectrafunc_ == DERIV) {  // La derivee du spectre
 | 
|---|
 | 266 |       if(spectrapower_ == POWER) //  W/... 
 | 
|---|
 | 267 |         {if(spectraapprox_==PLANCK) x=3.830016095; else if(spectraapprox_==WIEN) x=4.;}
 | 
|---|
 | 268 |       else if(spectrapower_ == PHOTON) //  Ph/s/...
 | 
|---|
 | 269 |         {if(spectraapprox_==PLANCK) x=2.575678888; else if(spectraapprox_==WIEN) x=3.;}
 | 
|---|
| [3115] | 270 |     }
 | 
|---|
 | 271 |   } else { // Longeur d'onde
 | 
|---|
| [3347] | 272 |     if(spectrafunc_ == VALUE) {  // Le spectre
 | 
|---|
 | 273 |       if(spectrapower_ == POWER) //  W/...
 | 
|---|
 | 274 |         {if(spectraapprox_==PLANCK) x=4.96511420; else if(spectraapprox_==WIEN) x=5.;}
 | 
|---|
 | 275 |       else if(spectrapower_ == PHOTON) //  Ph/s/...
 | 
|---|
 | 276 |         {if(spectraapprox_==PLANCK) x=3.9206904099; else if(spectraapprox_==WIEN) x=4.;}
 | 
|---|
 | 277 |     } else if(spectrafunc_ == DERIV) {  // La derivee du spectre
 | 
|---|
 | 278 |       if(spectrapower_ == POWER) //  W/...
 | 
|---|
 | 279 |         {if(spectraapprox_==PLANCK) x=5.969409190; else if(spectraapprox_==WIEN) x=6.;}
 | 
|---|
 | 280 |      else if(spectrapower_ == PHOTON) //  Ph/s/...
 | 
|---|
 | 281 |         {if(spectraapprox_==PLANCK) x=4.928119345; else if(spectraapprox_==WIEN) x=5.;}
 | 
|---|
| [3115] | 282 |     }
 | 
|---|
 | 283 |   }
 | 
|---|
 | 284 | 
 | 
|---|
 | 285 |   if(x<0.) return x;  // Rayleigh n'a pas de maximum
 | 
|---|
| [3347] | 286 |   if(spectravar_ == NU) return x / HsK_ *T_; // Frequence
 | 
|---|
| [3115] | 287 |   return HCsK_ / x /T_; // Longeur d'onde
 | 
|---|
 | 288 | }
 | 
|---|
 | 289 | 
 | 
|---|
 | 290 | double PlanckSpectra::FindMaximum(double eps)
 | 
|---|
 | 291 | // Retourne le maximum des spectres (a la precicion eps)
 | 
|---|
 | 292 | {
 | 
|---|
| [3347] | 293 |   if(spectraapprox_ == RAYLEIGH) {  // Pas de maximum pour les spectres de Raleigh
 | 
|---|
| [3115] | 294 |     cout<<"PlanckSpectra::FindMaximum : no maximum for Raleigh spectra"<<endl;
 | 
|---|
 | 295 |     throw ParmError("PlanckSpectra::FindMaximum : no maximum for Raleigh spectra");
 | 
|---|
 | 296 |   }
 | 
|---|
 | 297 |   if(eps<=0.) eps = 0.001;
 | 
|---|
 | 298 | 
 | 
|---|
 | 299 |   double xmax = WienLaw(), wmax=(*this)(xmax);
 | 
|---|
 | 300 |   double xlim[2]={xmax,xmax};
 | 
|---|
 | 301 | 
 | 
|---|
 | 302 |   // Encadrement du maximum par xlim[0] et xlim[1]
 | 
|---|
 | 303 |   while( (*this)(xlim[1])>=0.01*wmax ) xlim[1] *= 2.;
 | 
|---|
 | 304 |   while( (*this)(xlim[0])>=0.01*wmax ) xlim[0] /= 2.;
 | 
|---|
 | 305 |   //cout<<"FindMaximum: wmax="<<wmax<<" pour x=["<<xlim[0]<<","<<xlim[1]<<"]"<<endl;
 | 
|---|
 | 306 | 
 | 
|---|
 | 307 |   while( (xlim[1]-xlim[0])/xmax > eps ) {
 | 
|---|
 | 308 |    wmax=-1.;
 | 
|---|
 | 309 |    double dx = (xlim[1]-xlim[0])/10.;
 | 
|---|
 | 310 |    for(double x=xlim[0]; x<=xlim[1]; x+=dx) {
 | 
|---|
 | 311 |      double f=(*this)(x);
 | 
|---|
 | 312 |      if(f>wmax) {wmax=f; xmax=x;}
 | 
|---|
 | 313 |    }
 | 
|---|
 | 314 |    //cout<<"...wmax="<<wmax<<" pour xmax="<<xmax<<" dx="<<dx<<endl;
 | 
|---|
 | 315 |    xlim[0] = xmax-dx*1.1; xlim[1] = xmax+dx*1.1;
 | 
|---|
 | 316 |  }
 | 
|---|
 | 317 | 
 | 
|---|
 | 318 | 
 | 
|---|
 | 319 |   //cout<<"wmax="<<wmax<<" pour x="<<xmax<<"  dx="<<xlim[1]-xlim[0]<<endl;
 | 
|---|
 | 320 |   return xmax;
 | 
|---|
 | 321 | }
 | 
|---|
| [3325] | 322 | 
 | 
|---|
 | 323 | }  // Fin namespace SOPHYA
 | 
|---|